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 (2)

  1. Leo Bala BH MG says:

    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    

Skip to main content