Este es un ejemplo de los documentos de Glib para g_cond_wait() :
gpointer current_data = NULL; GMutex data_mutex; GCond data_cond; void push_data (gpointer data) { g_mutex_lock (&data_mutex); // (3) current_data = data; g_cond_signal (&data_cond); g_mutex_unlock (&data_mutex); // (4) } gpointer pop_data (void) { gpointer data; g_mutex_lock (&data_mutex); // (1) while (!current_data) g_cond_wait (&data_cond, &data_mutex); // (2) data = current_data; current_data = NULL; g_mutex_unlock (&data_mutex); // (5) return data; }Pasemos ahora a través de esto:
pop_data() , data_mutex está bloqueado (1)g_cond_wait() , se desbloquea data_mutex (2), el primer subproceso está esperandopush_data() , data_mutex está bloqueado (3)data_mutex (4)g_cond_wait() y desbloquea data_mutex nuevamente (5) Los documentos dicen que desbloquear un mutex no bloqueado no está definido. ¿Significa esto que el ejemplo contiene un error? ¿O g_cond_wait() bloqueará el mutex antes de salir?
Los documentos dicen que desbloquear un mutex no bloqueado no está definido. ¿Significa esto que el ejemplo contiene un error? ¿O g_cond_wait() bloqueará el mutex antes de salir?
No hay ningún error aquí. No hay desbloqueo de un mutex que no estaba bloqueado en el código. g_cond_wait() bloqueará el mutex cuando regrese.
Thread1 llama a g_cond_wait() con exclusión mutua bloqueada y g_cond_wait() desbloquea atómicamente la exclusión mutua y espera la condición. Después de esto, thread2 bloquea el mutex y realiza la operación, luego envía una señal a thread1 que está esperando en g_cond_wait() . Pero thread1 no puede continuar porque el mutex aún no está disponible (thread2 aún no lo ha desbloqueado). Entonces, después de que la llamada g_mutex_unlock() en thread2 lo desbloquea, g_cond_wait() en thread1 bloquea el mutex y la llamada regresa.
Sí, el mutex se vuelve a bloquear después de la espera. De los documentos simplistas para g_cond_wait() :
Cuando esta función regresa, mutex se bloquea nuevamente y es propiedad del subproceso de llamada.