2011-01-05 16 views
6

Lo siento por mi inglés, soy ruso.Bloquear mutex en un hilo y desbloquearlo en el otro

¿Este código será correcto y portátil?

void* aThread(void*) 
{ 
    while(conditionA) 
    { 
     pthread_mutex_lock(mutex1); 
     //do something 
     pthread_mutex_unlock(mutex2); 
    } 
} 

void* bThread(void*) 
{ 
    while(conditionB) 
    { 
     pthread_mutex_lock(mutex2); 
     //do something 
     pthread_mutex_unlock(mutex1); 
    } 
} 

En realidad, en la aplicación objetivo Tengo tres hilo - dos para escribir una matriz y una para la lectura. Y lo necesito justo después de que uno de los subprocesos que cambia el tercer subproceso muestra los contenidos de la matriz.

Respuesta

10

No lo es. Si el hilo A llega a mutex_unlock (2) antes de que el hilo B llegue a mutex_lock (2), se enfrenta a un comportamiento indefinido. No debes desbloquear el mutex de otro hilo tampoco.

El pthread_mutex_lock Open Group Base Specification dice así:

Si el tipo de exclusión mutua es PTHREAD_MUTEX_NORMAL [...] Si un hilo intenta desbloquear un mutex que no ha bloqueado o un mutex que es comportamiento resulta desbloqueados, no definidos.

+0

Ok. Pero ¿qué hay de desbloquear mutex que se había bloqueado en otro hilo? ¿Comportamiento indefinido también? –

+4

Como se dice: "si un hilo intenta desbloquear un mutex que no ha bloqueado ... UB" – user562374

3

Como user562734's answer says, la respuesta es no, no se puede desbloquear un hilo bloqueado por otro hilo.

Para lograr la sincronización lectora/grabadora que desea, debe usar las variables de condición - pthread_cond_wait(), pthread_cond_signal() y funciones relacionadas.

+0

Los semáforos también son a veces útiles para situaciones en las que desea "desbloquear el bloqueo de otro hilo". En realidad, son una gran solución por el hecho de que el uso recomendado documentado de 'pthread_atfork' invoca un comportamiento indefinido. :-) –

0

Algunas implementaciones permiten bloquear y desbloquear hilos en ser diferentes.

#include <iostream> 
#include <thread> 
#include <mutex> 

using namespace std; 

mutex m; 

void f() {m.lock(); cout << "f: mutex is locked" << endl;} 

void g() {m.unlock(); cout << "g: mutex is unlocked" << endl;} 

main() 
{ 
     thread tf(f); /* start f       */ 
     tf.join();  /* Wait for f to terminate   */ 
     thread tg(g); /* start g       */ 
     tg.join();  /* Wait for g to terminate   */ 
} 

Este programa grabados

f: mutex cerrado g: mutex está desbloqueado

sistema es Linux Debian, gcc 4.9.1. -std = C++ 11.

+0

¿La implementación de gcc 4.9.1 lo dice explícitamente? Si no y tu respuesta solo proviene de experimentos, sigue siendo UB, aunque en este caso parece estar funcionando. –

Cuestiones relacionadas