Welcome to MSDN Blogs Sign in | Join | Help

LUTI @ Microsoft


A tecnologia detalhada, descomplicada e bem empregada
==== Docendo Discimus ====

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

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

Published Friday, February 22, 2008 4:04 PM by Luciano Caixeta Moreira

Filed under:

Attachment(s): Threading_20080222.zip

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# Basketball Chat &raquo; Blog Archive &raquo; Condi????o de corrida @ Monday, April 21, 2008 4:45 AM

PingBack from http://www.basketballs-sports.info/basketball-chat/?p=136

Basketball Chat &raquo; Blog Archive &raquo; Condi????o de corrida

Leave a Comment

(required) 
required 
(required) 

  
Enter Code Here: Required
© 2009 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement  
Page view tracker