2009-08-10 7 views
12

He estado usando boost::mutex::scoped_lock de esta manera:¿Por qué Boost scoped_lock no desbloquea el mutex?

void ClassName::FunctionName() 
{ 
    { 
    boost::mutex::scoped_lock scopedLock(mutex_); 
    //do stuff 
     waitBoolean=true; 
    } 
    while(waitBoolean == true){ 
     sleep(1); 
    } 
    //get on with the thread's activities 
} 

Básicamente se establece waitBoolean, y las otras señales de hilo que se hace estableciendo waitBoolean en false;

Esto no parece funcionar, sin embargo, porque el otro hilo no puede obtener un bloqueo en mutex_ !!

Estaba asumiendo que al ajustar el scoped_lock entre paréntesis terminaría su bloqueo. Este no es el caso? La lectura en línea dice que solo abandona el mutex cuando se llama al destructor. ¿No será destruido cuando salga del alcance local?

señalización de la parte de código:

while(running_){ 
    boost::mutex::scoped_lock scopedLock(mutex_); 
    //Run some function that need to be done... 
    if(waitBoolean){ 
     waitBoolean=false; 
    } 
} 

Gracias!

+1

El objeto scoped_lock se destruye en el corchete de cierre y se libera el mutex. Por favor, publique la parte de señalización del código. Por cierto, un boost :: condition_variable es mejor para sus necesidades – neuro

+0

Ver bien su código de señalización puede funcionar en ciertos casos, pero depende del procesamiento que haga (sus comentarios). Si hay otra sincronización, es peor. Una variable de condición es la forma de hacerlo. He publicado el código que uso para hacer este tipo de sincronización. – neuro

+0

El "trabajo" del hilo de señalización no bloquea nada más. Se ejecuta de forma independiente. – Alex

Respuesta

16

El scoped_lock debería liberarse al final del alcance. Sin embargo, no bloquea el waitBoolean cuando lo está bucleando, lo que sugiere que no lo protege adecuadamente en otros lugares también, como p. donde está establecido en falso, y terminarás con condiciones desagradables de carrera.

Yo diría que debería usar un boost :: condition_variable para hacer este tipo de cosas, en lugar de sleep + comprobación de hilos inseguros.

22

Para sincronizar dos hilos, use una variable de condición. Ese es el estado de la forma en el arte para sincronizar dos hilos de la forma que desee:

Usando impulso, la parte de espera es algo así como:

void BoostSynchronisationPoint::waitSynchronisation() 
{ 
    boost::unique_lock<boost::mutex> lock(_mutex); 

    _synchronisationSent = false; 
    while(!_synchronisationSent) 
    { 
     _condition.wait(lock); // unlock and wait 
    } 
} 

El notificar parte es algo así como:

void BoostSynchronisationPoint::sendSynchronisation() 
{ 
    { 
     boost::lock_guard<boost::mutex> lock(_mutex); 
     _synchronisationSent = true; 
    } 

    _condition.notify_all(); 
} 

El negocio con _synchronisationSent es evitar el encendido del espúreas: ver wikipedia

0

también sugeriría a marcar tan volátil que waitBo Olean, sin embargo, tienes que usar una condición o incluso mejor una barrera.

Cuestiones relacionadas