compréhension du pthread cond wait () et du pthread cond signal()

d'une manière générale, pthread_cond_wait() et pthread_cond_signal() sont appelés comme ci-dessous:

//thread 1:
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
do_something()
pthread_mutex_unlock(&mutex);

//thread 2:
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);  
pthread_mutex_unlock(&mutex);

Les étapes sont

  1. pthread_cond_wait(&cond, &mutex); est appelé, il déverrouille le mutex

  2. Thread 2 verrouille le mutex et appelle pthread_cond_signal(), qui déverrouille le mutex

  3. dans thread 1,pthread_cond_wait() est appelée et verrouille le mutex

maintenant dans thread 2, après pthread_cond_signal() est appelée, pthread_mutex_unlock(&mutex) va exécuter, il me semble qu'il veut déverrouiller un le mutex qui est maintenant verrouillé par le thread 1. Il n'y a rien de mal dans ma compréhension?

en outre, il me semble aussi que pthread_cond_wait() peut être appelé par seulement 1 thread pour la même paire cond-mutex. Mais il y a un dicton "la fonction pthread_cond_signal() doit débloquer au moins un des threads qui sont bloqués sur la variable de condition spécifiée cond (si des threads sont bloqués sur cond)."Donc, cela veut dire pthread_cond_wait() peut être appelé par beaucoup des fils pour la même paire cond-mutex?

26
demandé sur JasonMArcher 2013-05-13 17:07:54

2 réponses

pthread_cond_signal ne déverrouille pas le mutex (il ne peut pas car il n'a aucune référence au mutex, alors comment pourrait-il savoir quoi déverrouiller? En fait, le signal n'a pas besoin d'avoir de connexion avec le mutex; le thread de signalisation n'a pas besoin de tenir le mutex, bien que pour la plupart des algorithmes basés sur des variables de condition il le fera.

pthread_cond_wait déverrouille le mutex juste avant qu'il ne s'endorme (comme vous le constatez), mais ensuite il rallume le mutex (qui peut nécessiter une attente) quand il est signalé, avant qu'il ne se réveille. Ainsi, si le fil de signalisation retient le mutex (le cas habituel), le fil d'attente ne se poursuivra pas jusqu'à ce que le fil de signalisation déverrouille également le mutex.

l'usage commun de La condition de vars est quelque chose comme:

thread 1:
    pthread_mutex_lock(&mutex);
    while (!condition)
        pthread_cond_wait(&cond, &mutex);
    /* do something that requires holding the mutex and condition is true */
    pthread_mutex_unlock(&mutex);

thread2:
    pthread_mutex_lock(&mutex);
    /* do something that might make condition true */
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mutex);

les deux threads ont une structure de données partagée à laquelle le mutex protège l'accès. Le premier fil veut attendre jusqu'à ce qu'une condition soit vraie, puis immédiatement faire une opération (sans condition de course possibilité pour un autre fil à venir dans entre le contrôle de l'état et l'action et faire la condition fausse. Le second fil fait quelque chose qui pourrait rendre la condition vraie, donc il doit réveiller tous ceux qui pourraient être en train de l'attendre.

60
répondu Chris Dodd 2013-05-13 14:18:15

Voici un exemple typique: thread 1 attend une condition, qui peut être remplie par thread 2.

nous utilisons un mutex et une condition.

pthread_mutex_t mutex;
pthread_cond_t condition;

thread 1:

pthread_mutex_lock(&mutex); //mutex lock
while(!condition){
    pthread_cond_wait(&condition, &mutex); //wait for the condition
}

/* do what you want */

pthread_mutex_unlock(&mutex);

filetage 2:

pthread_mutex_lock(&mutex);

/* do something that may fulfill the condition */

pthread_mutex_unlock(&mutex);
pthread_cond_signal(&condition); //wake up thread 1

Modifier

Comme vous pouvez le voir dans le pthread_cond_wait manuel:

il libère atomiquement mutex et provoque le blocage du thread appelant la variable de condition cond; atomiquement signifie ici "atomiquement à l'égard de l'accès par un autre thread pour le mutex et puis la variable de condition".

5
répondu Ludzu 2017-10-23 03:10:55