variable de condición - ¿por qué llamar a pthread cond signal() antes de llamar a pthread cond wait() es un error lógico?


Está escrito en el tutorial de hilos POSIX https://computing.llnl.gov/tutorials/pthreads / que es un error lógico.

Mi pregunta es ¿por qué es un error lógico?

En mi programa necesito usar estas señales, sin embargo no puedo garantizar que habrá un hilo que estará en estado _cond_wait. Intenté probarlo y no pasó nada. ¿Esto puede causar un comportamiento inesperado o peor?

¡Gracias!

Author: curiousguy, 2011-04-04

4 answers

La respuesta de blaze se acerca más, pero no está totalmente clara:
las variables condicionales solo deben usarse para indicar un cambio en una condición .

El hilo 1 comprueba una condición. Si la condición no cumple, espera en la variable condición hasta que la condición cumpla. Debido a que la condición se comprueba primero, no debería importarle si la variable de condición fue señalada:

pthread_mutex_lock(&mutex); 
while (!condition)
    pthread_cond_wait(&cond, &mutex); 
pthread_mutex_unlock(&mutex);

El hilo 2 cambia la condición y señala el cambio a través de la variable condición. A él no le importa si los hilos están esperando o no:

pthread_mutex_lock(&mutex); 
changeCondition(); 
pthread_mutex_unlock(&mutex); 
pthread_cond_signal(&cond)

La conclusión es: la comunicación se realiza a través de alguna condición. Una variable de condición solo despierta los hilos en espera para que puedan verificar la condición .

Ejemplos de condiciones:

  • La cola no está vacía, por lo que se puede tomar una entrada de la cola
  • Se establece una bandera booleana, por lo que el hilo espera s hasta que la otra señal de hilo está bien continuar
  • algunos bits en un conjunto de bits se establecen, así que el hilo de espera puede manejar los eventos correspondientes

Ver también pthread ejemplo

 35
Author: stefaanv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-09 10:36:33

Mis 2 centavos: No conozco los efectos secundarios de llamar a *pthread_cond_signal()* cuando no se ha bloqueado ningún hilo llamando a *pthread_cond_wait()*. Esto es realmente un detalle de implementación Lo que creo es que, si tu modelo threading / timimg no garantiza el orden correcto entre espera y señal, probablemente deberías considerar un mecanismo de sincronización diferente[como un simple semáforo , por ejemplo] cuando puedes señalar el semáforo desde el hilo B incluso si el hilo A no ha alcanzado la sincronización punto. Cuando el hilo A alcance el punto de sincronización, encontrará el semáforo incrementado y entrará en la sesión crítica.

 4
Author: sergico,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-04 09:58:32

Una variable de condición permite que un hilo despierte a otro de una espera. Funcionan solo si hay un hilo esperando en el momento en que se activa la condición. La forma de garantizar que este sea el caso es que el hilo de espera bloquee un mutex que está vinculado a la condición, y que el hilo de señalización bloquee ese mutex antes de activar la condición. En otras palabras, el hilo de señalización solo puede bloquear el mutex y activar la condición si el otro hilo tenía el mutex bloqueado pero ahora está esperando.

Estoy más familiarizado con boost, así que lo usaré en este ejemplo:

// A shared mutex, global in this case.
boost::mutex myMutex;

// Condition variable
boost::condition_variable myCondition;

void threadProc()
{
    // Lock the mutex while the thread is running.
    boost::mutex::scoped_lock guard( myMutex );

    while( true )
    {
        // Do stuff, then...

        myCondition.wait( guard ); // Unlocks the mutex and waits for a notification.
    }
}

void func()
{
    // Function wants to trigger the other thread. Locks the mutex...
    boost::mutex::scoped_lock guard( myMutex );

    // Since the mutex is locked, we know that the other thread is
    // waiting on the condition variable...
    myCondition.notify_all();
}

Señalar una variable de condición cuando no hay una espera correspondiente es un error lógico porque nada recibirá la señal. Las variables de condición no permanecen en un estado señalado.

 3
Author: RobH,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-04 09:52:26

Si no le importa que esta señal se pierda, no hay error. Es solo un error si esperas que el hilo en espera se despierte de cond_wait() inmediatamente.

Dado que este es el caso de uso habitual para pthread_cond, el tutorial llama a este error lógico. Pero nada se estrellará y no se producirá ningún comportamiento inesperado. En el flujo de ejecución normal, cond_signal() todavía puede emitirse cuando no hay subprocesos en cond_wait (): por ejemplo, todos los lectores pueden estar simplemente procesando mensajes cuando writer agrega otra pieza de datos en la cola.

 3
Author: blaze,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-04 10:29:07