Partager via


Condição de corrida

Ao invés de fazer artigos longos, vou seguir as sugestões e postar pequenos trechos de código isolados (quem sabe um dia vira artigo). Hoje eu estava aqui pensando sobre programação paralela e fui brincar com o .NET. Segue um exemplo de condição de corrida.

Se eu executo um loop 100.000 vezes por 10 threads diferentes, cada uma incrementando um contador global em um, o que esperamos ao fim da execução é ver o valor de 1 milhão, certo? Só se você implementou corretamente sua aplicação multithreaded, com os devidos mecanismos de sincronização. Execute e compare os resultados.

Em anexo está o projeto (VS2008) para vocês brincarem e não vejo porque não compilar até no framework 1.1. Fazia um tempão que não brincava com threads, então em uma programação rápida, deve ter alguma coisa que melhorar.

using System;

using System.Collections.Generic;

using System.Text;

using System.Threading;

using System.Diagnostics;

namespace Threading

{

    public class RaceCondition

    {

        int contadorGeral;

        object ElementoSync = new object();

               

        public void ComecaCorrida(Boolean SemControle)

        {

            contadorGeral = 0;

            Thread[] ts = new Thread[10];

            for (int i = 0; i < 10; i++)

            {

                // Cria threads e define qual método o delegate vai chamar, além de dar nome aos bois

                ts[i] = new Thread(SemControle ? new ThreadStart(SemControleIncremento) : new ThreadStart(ComControleIncremento));

                ts[i].Name = "Thread " + i.ToString();

                Console.WriteLine(DumpThread(ts[i]));

            }

           

            foreach (Thread t in ts) t.Start();

            foreach (Thread t in ts) t.Join();

        }

        private string DumpThread(Thread t)

        {

            return "ID Thread: " + t.ManagedThreadId.ToString() + " - " + t.Name;

        }

        private void SemControleIncremento()

        {

            int valorlocal = 0;

            Random rnd = new Random();

            for (int i = 0; i < 100000; i++)

            {

                valorlocal = contadorGeral;

                // Estou usando o spinwait para não causar causar o bloqueio/escalonamento das threads o tempo todo (comportamento do Thread.sleep),

                // então mantenho a thread rodando por x ciclos de CPU. O valor 500 é suficiente para não dar tempo da execução do loop

                // acabar dentro do quantum alocado para a thread corrente.

                Thread.SpinWait(rnd.Next(500));

                //Thread.SpinWait(rnd.Next(50));

                //Thread.Sleep(rnd.Next(5));

                contadorGeral = valorlocal + 1;

            }

            Console.WriteLine(DumpThread(Thread.CurrentThread) + " " + contadorGeral.ToString());

        }

        private void ComControleIncremento()

        {

            int valorlocal = 0;

            Random rnd = new Random();

            // Sincroniza o acesso a esta região de código para evitar condição de corrida.

            lock (ElementoSync)

            {

                for (int i = 0; i < 100000; i++)

                {

                    valorlocal = contadorGeral;

                    Thread.SpinWait(rnd.Next(500));

                    //Thread.SpinWait(rnd.Next(50));

                    //Thread.Sleep(rnd.Next(5));

                    contadorGeral = valorlocal + 1;

                }

            }

            Console.WriteLine(DumpThread(Thread.CurrentThread) + " " + contadorGeral.ToString());

        }

    }

}

        static void Main(string[] args)

        {

            new RaceCondition().ComecaCorrida(true);

            Console.WriteLine();

            new RaceCondition().ComecaCorrida(false);

            Console.ReadLine();

        }

[]s

Luciano Caixeta Moreira

luciano.moreira@microsoft.com

=============================================================

This posting is provided "AS IS" with no warranties, and confers no rights

=============================================================

Threading_20080222.zip

Comments

  • Anonymous
    April 20, 2008
    PingBack from http://www.basketballs-sports.info/basketball-chat/?p=136

  • Anonymous
    September 27, 2010
    Caro Luciano !! bom vi aqui seu algoritmo  achei maneiro !! cara estou cursando aqui em Belo Horizonte na Faculdade Uni BH , o Curso de Tecnologia da Informaçao. hoje particpei da aula de S.O , Sistemas Operacionais ,vim antenado para estudar em casa .heheheh bom acho que vc me ajudou um pouco....... Condiçao de corrida ,, Semafaros enfim to na area aqui  um futuro   GTI  no mercado  desde ja  agradeço e parabéns Leo Bala BH MG  (curso GTI UNI BH )   flws