Sincronização condicional usando pthreads

Vimos o uso de objetos de sincronização para impedir múltiplas atualizações, quando usamos threads, no post anterior. Os mutexes são “portas” no estilo tudo-ou-nada. Ou a porta está aberta ou está fechada. Pthreads estende o conceito usando outro objeto de sincronia: variáveis de condição.

Imagine que uma de suas threads realize um loop while da seguinte maneira:

while (x <= y) { ... }

Onde x e y são variáveis globais e, no interior do loop, elas não são atualizadas. Ou seja, uma outra thread atualiza x, por exemplo. Um loop assim pode consumir um bocado de recursos de CPU. Não seria interessante interromper o loop, colocando a thread “para dormir”, até que a thread receba um sinal de que pode continuar (quando ‘x’ for maior que ‘y’, por exemplo)?

O código fica, mais ou menos assim:

int x, y;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

void *thread1(void *data)
{
  pthread_mutex_lock(&mutex);

  while (x <= y)
  {
    /* ... */

    /* Interrompe a thread até receber um 'sinal'! */
    pthread_cond_wait(&cond, &mutex);

    /* ... */
  }

  pthread_mutex_unlock(&mutex);
  return NULL;
}

void *thread2(void *data)
{
  pthread_mutex_lock(&mutex);

  /* ... */

  x = y + 1;
  pthread_cond_signal(&cond);

  /* ... */

  pthread_mutex_unlock(&mutex);

  return NULL;
}

Ao encontrar pthread_cond_wait() o mutex é liberado e thread é suspensa. Na segunda thread, quando x é atualizado, chamamos pthread_cond_signal() para dizemos para a outra thread que estão “esperando” que podem continuar… Repare que, quanto a thread 1 continuar, pthread_cond_signal() retornará com o mutex travado.

Neste caso ai em cima, poderíamos usar pthread_cond_broadcast() se tivéssemos mais que uma thread esperando pela condição. A função pthread_cond_signal() é mais eficiente.

Interessante, não?

Anúncios

Deixe um comentário

Faça o login usando um destes métodos para comentar:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s