Avançar para o conteúdo principal

Concorrência

Na era dos processadores multicore a execução concorrente faz cada fez mais sentido, de que serve ter um processador com 8 núcleos se os nossos programas só correm uma tarefa de cada vez, ocupando assim um só núcleo.

Cada vez mais é necessário pensar os programas como pequenas tarefas e quando possível executar essas tarefas concorrentemente, ou seja, em simultâneo, porquê esperar que o disco guarde os dados quando podemos criar um thread que executa a tarefa sem interromper a interface.

A classe THREAD é, na plataforma .NET, o ponto de partida para a execução concorrente.
Com esta classe é possível definir prioridades de execução, pausar e retomar as threads bem como sincronizar diferentes threads entre si, criando relações de execução entre diferentes processos.



Para criar uma nova thread na plataforma .NET o programador precisa de ter uma classe com um método que não possua parâmetros de entrada e que devolva void, ou seja não devolve nada.
É este método que será executado quando a nova thread for iniciada.

Para este post vamos criar uma interface que deverá demonstrar a execução concorrente de três threads, para isso construimos o único form do nosso programa assim:

Os numericupdown vão servir para indicar o tempo de espera de cada thread, assim o valor máximo é 1000, que corresponde a um segundo. Quanto maior este valor mais lento será o enchimento da barra.

As progressbar devem ter um valor máximo de 100, que é o valor por defeito.
A ideia é que cada progressbar vá enchendo de cada vez que o código da thread completa um ciclo de execução.

Agora a classe das threads:

    class tarefa
    {
        private int tempo;  //tempo de espera por cada ciclo de execução
        public int valor;    //valor actual da thread
        private int valormax;   //valor máximo que interrompe a execução da thread
       
        //construtor
        public tarefa(int tempo, int valormax)
        {
            valor = 1;
            this.tempo = tempo;
            this.valormax = valormax;
        }
        //método onde a execução da thread ocorre
        public void executa()
        {
            while (true)
            {
                Thread.Sleep(tempo);
                valor++;
                if (valor >= valormax) break;  //aqui para o ciclo e a thread "morre"
            }
        }
    }

Um clique no botão Iniciar demo vai executar o seguinte código:

//Esta linha cria um objecto da classe tarefa

            t1 = new tarefa((int)this.numericUpDown1.Value,(int)this.progressBar1.Maximum);
//Esta linha cria uma thread associada ao método executa do objecto
            thr1 = new Thread(new ThreadStart(t1.executa));
//As restantes linhas criam mais dois objectos
            t2 = new tarefa((int)this.numericUpDown2.Value,  (int)this.progressBar2.Maximum);
            thr2 = new Thread(new ThreadStart(t2.executa));
            t3 = new tarefa((int)this.numericUpDown3.Value,  (int)this.progressBar3.Maximum);
            thr3 = new Thread(new ThreadStart(t3.executa));
//Estas linhas iniciam a execução das três threads
            thr1.Start();
            thr2.Start();
            thr3.Start();
            timer1.Enabled = true;

O botão Parar para as três threads:

            thr1.Abort();
            thr2.Abort();
            thr3.Abort();

O botão Pausar/Continuar pausa as threas e remota a sua execução:

            if (this.button3.Text == "Pausar")
            {
                thr1.Suspend();
                thr2.Suspend();
                thr3.Suspend();
                this.button3.Text = "Continuar";
                this.button2.Enabled = false;
            }
            else
            {
                thr1.Resume();
                thr2.Resume();
                thr3.Resume();
                this.button3.Text = "Pausar";
                this.button2.Enabled = true;
            }

O método Suspend coloca a execução em suspenso e o método Resume retoma a execução.

Por fim adicionei um timer para actualizar as progressbar refletindo os valores das threads.

O projecto está aqui.




Comentários

Mensagens populares deste blogue

Upgrade do Windows Home para Pro sem formatar

 Há algum tempo que tentava fazer o upgrade do meu Windows 10 da versão Home para a versão Pro, mas chegava sempre a um ponto em que me era solicitado para formatar o sistema e não estava para isso. Finalmente conseguinte seguindo estes passos: - seguinte estes passos  utilizei uma das chaves genéricas para o Windows 10 Pro e fui a Settings > Update & Security > Activation > Change the product key; - após inserir uma das chaves o Windows instala as funcionalidades Pro e pede para reiniciar; - agora tem o Windows Pro mas não está ativado, assim fui ao site urcdkeys  onde comprei uma chave para o Windows Pro por menos de €20; - com essa chave voltei a funcionalidade Change the product key e ativei o Windows; - e pronto, Windows Pro ativado sem formatar ou reinstalar. Importante : eu não tenho nada a ver com o site urcdkeys por isso a vossa experiência pode correr de forma diferente da minha.

Vamos fazer um carro com o Unity 3D

Neste artigo vamos fazer um carro, simples, com o Unity 3D. A ideia é utilizar o motor de física do Unity 3D para simular o comportamento do carro. Os passos a seguir são: [1] - Criar um projeto novo

Tem troco

Para hoje um pequeno programa que dá troco, bem dar não dá mas calcula o troco a dar em função das moedas disponíveis. Neste projeto vamos utilizar o novo Visual Studio 2012. Como era de se esperar vamos iniciar um projeto novo: Agora adicionamos os seguintes elementos:  - um botão para calcular as moedas a dar de troco  - um botão para repor o número de moedas iniciais disponíveis  - uma textbox para introduzir o valor a pagar  - uma textbox para introduzir o valor entregue  - umas labels para informar o utilizador do que deve introduzir e outra para mostrar o troco  - por fim uma grelha para mostrar os valores das moedas e as quantidades disponíveis de cada uma. A janela principal do programa fica assim: Agora o código, primeiro o evento load do formulário, neste vamos definir os valores das moedas e as respetivas quantidades Para guardar estes valores vamos necessitar de uma variável definida ao nível do formulário, logo abaixo da definição da class: Public Class Form1     Public mo