pthreads - threads - pthread tutorial linux
variable condicional pthread (5)
Del manual pthread_cond_signal :
Las funciones pthread_cond_broadcast () y pthread_cond_signal () no tendrán efecto si no hay threads actualmente bloqueados en cond.
Te sugiero que uses semáforos . Básicamente, cada vez que se inserta una tarea en la cola, "sube" el semáforo. El hilo de trabajo se bloquea en el semáforo al "bajarlo". Como se "activará" una vez para cada tarea, el hilo de trabajo continuará mientras haya tareas en la cola. Cuando la cola está vacía, el semáforo está en 0 y el hilo de trabajo se bloquea hasta que llega una nueva tarea. Los semáforos también manejan fácilmente el caso cuando llegó más de 1 tarea mientras el trabajador estaba ocupado. Tenga en cuenta que todavía tiene que bloquear el acceso a la cola para mantener las inserciones / eliminaciones atómicas.
Estoy implementando un hilo con una cola de tareas. Tan pronto como se agrega la primera tarea a la cola, el hilo comienza a ejecutarla.
¿Debo usar la variable de condición pthread para activar el hilo o hay un mecanismo más apropiado?
Si llamo a pthread_cond_signal()
cuando el otro hilo no está bloqueado por pthread_cond_wait()
sino que algo está haciendo, ¿qué ocurre? ¿Se perderá la señal?
Los semáforos son buenos si-y-solo-si su cola ya es segura para subprocesos. Además, algunas implementaciones de semáforos pueden estar limitadas por el valor del contador superior. Incluso es poco probable que se sobrepase el valor máximo.
La manera más simple y correcta de hacer esto es seguir:
pthread_mutex_t queue_lock;
pthread_cond_t not_empty;
queue_t queue;
push()
{
pthread_mutex_lock(&queue_lock);
queue.insert(new_job);
pthread_cond_signal(¬_empty)
pthread_mutex_unlock(&queue_lock);
}
pop()
{
pthread_mutex_lock(&queue_lock);
if(queue.empty())
pthread_cond_wait(&queue_lock,¬_empty);
job=quque.pop();
pthread_mutex_unlock(&queue_lock);
}
La señal se perderá, pero desea que la señal se pierda en ese caso. Si no hay ningún hilo para despertar, la señal no sirve para nada. (Si nadie está esperando algo, nadie debe ser notificado cuando sucede, ¿no?)
Con las variables de condición, las señales perdidas no pueden hacer que un hilo "duerma durante un incendio". A menos que realmente codifique un hilo para ir a dormir cuando ya hay un incendio, no es necesario "guardar una señal". Cuando comience el fuego, tu transmisión despertará cualquier hilo que duerma. Y tendrías que ser bastante tonto para codificar un hilo para ir a dormir cuando ya hay un incendio.
Como ya se sugirió, los semáforos deberían ser la mejor opción. Si necesita una cola de tamaño fijo solo use 2 semáforos (como en el clásico productor-consumidor).
En el código de artyom, sería mejor reemplazar "si" con "while" en la función pop (), para manejar la activación espuria.
Sin efectos.
Si comprueba cómo se implementa pthread_condt_signal, el condt usa varios contadores para verificar si hay algún subproceso en espera para reactivarse. por ejemplo, glibc-nptl
/* Are there any waiters to be woken? */
if (cond->__data.__total_seq > cond->__data.__wakeup_seq){
...
}