C# - Programação Paralela (Dividir para Conquistar)


Hoje eu vou escrever um pouco sobre programação paralela ou Parallel Programming apresentando os conceitos básicos relativos a este importante assunto.

Antes de continuar é bom definir alguns conceitos relacionados ao assunto:

A Computação paralela é uma forma de computação em que vários cálculos são realizados simultaneamente, operando sob o princípio de que grande problemas geralmente podem ser divididos em problemas menores, que então são resolvidos concorrentemente (em paralelo). (Widkipédia)

O modelo de programação paralela é um conjunto de tecnologias de software para expressar algoritmos paralelos e criar aplicações compatíveis com sistemas que suportam a computação paralela. Isso inclui as áreas de aplicações, linguagens de programação, compiladores, biblioteca (computação), sistemas de comunicação e I/O paralelo.

Devido a dificuldades da atual paralelização automática, pessoas tem que escolher um modelo de programação paralela apropriado ou uma forma de mistura deles para desenvolver suas aplicações sobre uma plataforma paralela.(Widkipédia)

Um processador pode executar somente um processo a cada instante e em um Sistema Operacional multitarefa, processos se alternam no uso do processador – cada processo é executado durante um quantum de tempo. Se houver N processadores, N processos podem ser executados simultaneamente.

Obs: Não confundir Paralelismo com Concorrência:

Execução concorrente está associada ao modelo de um servidor atendendo a vários
clientes através de uma política de escalonamento no tempo.

Execução paralela está associada ao modelo de vários servidores atendendo a vários clientes
simultaneamente no tempo.

As linguagens de programação podem então ser classificadas como seqüenciais,
concorrentes e paralelas.

Com a versão 4.0 do . NET Framework, a Microsoft introduziu um novo modelo para escrever aplicativos que precisam realizar múltiplas tarefas simultâneas; este modelo é conhecido como programação paralela, e a implementação é chamada de biblioteca paralela de tarefas(Task Parallel Library).

Diferentemente da abordagem tradicional para multitarefa, onde você pode criar e gerenciar um conjunto de tópicos em seu código, o novo modelo de programação paralela permite você se concentrar nas tarefas que você precisa para realizar e permite ao runtime criar e gerenciar as threads no seu lugar.

Há grande vantagem dessa abordagem é que seu código é focado nas tarefas que você precisa para executar e não na maneira pela qual eles serão executados.

A principal desvantagem é que ao usar este recurso você abre mão do controle direto do comportamento da sua aplicação e isso pode não ser o cenário ideal para aplicações que requeiram um controle e gestão mais refinado.

Para começar vamos mostrar como realizar tarefas simples usando a programação paralela.

Para realizar tarefas simples usando programação paralela basta usar o método Invoke da classe System.Threading.Parallel, passando uma instância do delegate System.Action para cada método que deseja executar.

O método Invoke da classe Parallel é a maneira mais simples de adicionar a multitarefa às suas aplicações.

Obs: O método Parallel.Invoke só pode ser usado para chamar métodos que não retornam um resultado;

Você simplesmente fornecer um conjunto de delegates Action, cada um dos quais envolve um método que você deseja executar. A . NET Framework cuida do resto e as threads são criadas e gerenciadas automaticamente em seu nome.

O exemplo a seguir chama três métodos simultaneamente e cada um que escreve uma série de mensagens para o console.

Usando os recursos da programação Paralela

Para simular uma tarefa demorada, esses métodos de chamada a Thread.Sleep afim de retardar o andamento do pedido de algo que você não faria com uma aplicação real.

Nós criamos os delegates Action explicitamente para tornar o exemplo mais claro possível, mas uma abordagem mais elegante seria usar expressões lambda.

Vamos abrir o Visual C# 2010 Express Edition e criar um novo projeto to tipo Console Application chamado ProgramacaoParalela;

No menu File->New Project selecione o template Visual C# e a seguir Console Application definindo o nome ProgramacaoParalela e clicando em OK;

Agora inclua o seguinte código no arquivo Programa.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ProgramacaoParalela
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Pressione ENTER para iniciar");
            Console.ReadLine();

            // Invocar os métodos que vamos executar
            Parallel.Invoke(
               new Action(exibirDias),
               new Action(exibirMeses),
               new Action(exibirCidades)
            );

            // Aguardar a continuação do programa
            Console.WriteLine("\nO método Main foi encerrado. Tecle Enter");
            Console.ReadLine();
        }

        static void exibirDias()
        {
            string[] diasArray = { "Segunda", "Terça", "Quarta","Quinta", "Sexta", "Sábado", "Domingo" };
            foreach (string dia in diasArray)
            {
               Console.WriteLine("Dia da semana: {0}", dia);
               Thread.Sleep(500);
            }
        }
       
        static void exibirMeses()
        {
            string[] messArray = { "Jan", "Fev", "Mar", "Abr","Mai", "Jun", "Jul",
                                   "Ago", "Set", "Out", "Nov", "Dec" };

            foreach (string mes in messArray)
            {
               Console.WriteLine("Mês : {0}", mes);
                Thread.Sleep(500);
            }
        }
       
        static void exibirCidades()
        {
            string[] cidadesArray = { "Londres", "New York", "Paris", "Tóquio","Sidney" };
            foreach (string cidade in cidadesArray)
            {
               Console.WriteLine("Cidade : {0}", cidade);
                Thread.Sleep(500);
            }
            }
        }
  }

O método Parallel.Invoke serve para executar processos que ocorrem eventualmente em paralelo e no exemplo estamos invocando 3 funções para realizar tarefas usando os conceitos da programação paralela.

O resultado da execução pode ser visto na figura abaixo:

A classe Parallel da plataforma .NET inclui também os seguintes métodos:

Os métodos Parallel.For() e Parallel.Foreach() são úteis se você tiver coleções sobre as quais deseja interagir ou deseja executar um número conhecido de vezes o mesmo código.

Tanto o Parallel.For como o Parallel.ForEach possuem várias sobrecargas que permitem parar ou interromper a execução do loop, monitorar o estado do circuito em outros segmentos, manter o estado de segmento local, finalizar objetos na thread-local, controlar o grau de concorrência, e assim por diante.

Para chamar métodos distintos usamos o Parallel.Invoke.

Pegue o projeto completo aqui: ProgramacaoParalela.zip

Eu sei é apenas C#, mas eu gosto...

Referências:


José Carlos Macoratti