logo
Contato | Sobre...        
rebarba rebarba

Rodrigo Strauss :: Blog

follow us in feedly

Win32: sincronização parte 2

Preparando esse post eu percebi que o post de sincronização parte 1 não explica nada sobre sincronização, só apresenta o problema que a sincronização resolve. Estou parecendo aqueles vendedores de empresas de software que gastam mais tempo tentando provar que você tem um problema do que realmente mostrando a solução. Agora chegou a hora de mostrar a solução. :-)

Como vimos na primeira parte, o maior problema em programação multithread é o compartilhamento de dados entre as threads. Existem duas solução para isso. A primeira e mais usada é sincronizar o acesso aos dados, de forma que somente uma thread por vez manipule os dados em questão. Ou seja, a solução envolve "eliminar" (notou as aspas?) o multithread da parte que ele atrapalha. A segunda e pouco usada opção é eliminar o compartilhamento dos dados, usando filas, controle restrito de ownership e trabalhando com cópias do dados. Esse é o enfoque usado pelo Erlang, uma nova linguagem de programação.

A forma mais básica para sincronização em vários SOs é o critical section. Esse recurso permite definir um trecho de código que é executado por várias threads, mas que precisa ser sincronizado entre elas. Sincronizado == somente uma thread pode executar esse trecho de código por vez.

Revisando a nossa classe de lista ligada, vamos ver quais são os dados da classe:

template<typename T>

class LinkedList
{
  struct NODE
  {
    NODE* previous;
    NODE* next;
    T data;
  };
 
  NODE rootNode_;
  unsigned int count_;

 ...

A princípio parece que precisamos sincronizar o rootNode_ e o count_. Apesar disso estar correto, não é simples assim, não esqueça que todos os nós apontados pelo rootNode_ são dados controlados pela classe, que também precisam ser sincronizados.

Olhando o fonte dessa classe, todos os métodos manipulam ou lêem essas duas variáveis. A forma mais fácil e óbvia seria cercar com um critical section o corpo de todas as funções da classe.

Em Win32, um critical section é definido pelo objeto (surpresa!) CRITICAL_SECTION. Esse objeto deve ser inicializado e terminado, dessa forma:

CRITICAL_SECTION cs;

//
// adivinha?
//
InitializeCriticalSection(&cs);

//
// aqui entramos no critical section. Quando uma thread está "dentro" de
// um critical section, se alguma outra thread tentar entrar ficará
// travada dentro da funcão EnterCriticalSection até que a primeira
// thread chame LeaveCriticalSection. Isso garante que somente uma thread
// executará esse trecho de código em um dado momento.
//
EnterCriticalSection(&cs);

//
// Saímos do critical section. Isso faz com que a próxima thread que estiver
// esperando no ponto do EnterCriticalSection seja liberada. Note que somente
// uma thread é liberada por vez. Caso mais de uma thread esteja esperando, elas
// são liberadas na ordem que chegaram "na portinha" do critical section
//
LeaveCriticalSection(&cs);

//
// análogo ao CloseHandle
//
DeleteCriticalSection(&cs);

Resumindo: o Critical Section cria um "gargalo", onde só passa uma thread de cada vez. Ah, existe uma coisa interessante a ser acrescentada à explicação do post sobre threads: as threads permitem que um processo execute várias linhas de execução ao mesmo tempo, mas essas linhas de execução podem rodar o mesmo código, que está no mesmo lugar na memória. Ou seja, elas compartilham dados e código executável.

No próximo post iremos para o exemplo prático.


Em 30/01/2009 16:17, por Rodrigo Strauss


  
 
 
Comentários
Ramon | em 01/02/2009 | #
Primeiramente eu quero lhe agradecer pelo trabalho que você faz aqui.Ajuda muitas pesoas.Eu sei que a minha pergunta não tem muito a ver com a matéria acima mas lá vai.

Eu vi na matéria sobre flexibilidade que você escreveu, que você citou a linguagem Ocaml.Você tem interesse em aprender essa linguagem?E você tem idéia de quanto tempo é necessário para ficar bom em C++?

Desculpe a pergunta fora de hora.Espero que você possa me ajudar.

Obrigado
Rodrigo Strauss | website | em 01/02/2009 | #
Eu já li um tutorial de OCaml, mas estou estudando computação distribuída no momento e não estou com vontade de estudar outras linguagens agora. Eu ia escrever que não tenho tempo para isso agora, mas falta de tempo é uma desculpa bem furada, para praticamente qualquer coisa. :-)

Sobre o tempo de C++, é bem relativo, depende do seu esforço. Mas com um ano de C++, ou até mesmo, você já consegue fazer bastante coisa.
Ramon | website | e-mail | em 05/02/2009 | #
Obrigado por responder minha pergunta.Vou me esforçar para aprender.
Robson L. | em 02/04/2009 | #
Seu site é muito bom. Tem bons artigos e muita informação útil para quem está começando (como eu) ou não. Mas, é uma pena estar tão abandonado ultimamente...
Marcelo S. Muzzi | e-mail | em 17/05/2009 | #
Estou começando- já li alguns livros e domino as partes teóricas até pointers - em C++ e estou vendo que Win32 é muito importante em C++. Tens alguma dica de livro sobre Win32 que esteja a venda no Brasil(em inglês serve) e que não seja muito caro?

Obrigado.
Charles | em 20/05/2009 | #
Vamos fazer uma campanha: volta, Rodrigo!!!
Rodrigo Strauss | website | em 20/05/2009 | #
Marcelo, veja http://www.1bit.com.br/content.1bit/weblog/faq_win32
Marcelo S. Muzzi | e-mail | em 29/05/2009 | #
Uhum.

Vou ver estes livros.

Mas acho que antes vou olhar typedef e o resto. Para que eu seja capaz de aprender todos os pontos de Windows.
Algo a dizer?
Nome:


Site:


E-mail:


Escreva o número vinte e seis:


 Não mostre meu e-mail no site, não serve pra nada mesmo...

Comentário





Os comentários devem ser sobre assuntos relativos ao post, eu provavelmente apagarei comentários totalmente offtopic. Se quiser me enviar uma mensagem, use o formulário de contato. E não esqueça: isso é um site pessoal e eu me reservo o direito de apagar qualquer comentário ofensivo ou inapropriado.
rebarba rebarba
  ::::