Rendement garanti avec pthread_cond_wait et pthread_cond_signal

En supposant que j’ai un programme C avec 3 threads POSIX, partageant une variable globale, un mutex et une variable de condition, dont deux exécutent le psuedocode suivant:

...process data... pthread_mutex_lock( &mutex ); variable = data_ptr; pthread_cond_signal( &cond ); pthread_mutex_unlock( &mutex ); 

Et la troisième course:

 while(1) { while( variable == NULL ) { pthread_mutex_wait( &cond, &mutex ); } printf( "Data is %d", *variable ); } 

Est-il prudent de supposer que le troisième thread verra les données de chacun des deux premiers?

En d’autres termes, si un thread attend un mutex et une variable de condition, est-il prudent de supposer que ce sera le prochain à obtenir le verrou s’il est signalé, plutôt qu’un autre thread qui attend peut-être sur le fermer à clé?

Pthread_mutex_wait n’existe pas. Je suppose que vous voulez dire:

 pthread_mutex_lock(&mutex); /* ... */ while (1) { while (variable == NULL) pthread_cond_wait(&cond, &mutex); printf("Data is %d", *variable); } /* ... */ pthread_mutex_unlock(&mutex); 

Il n’y a aucune garantie que le troisième thread verra les données des deux. pthread_cond_signal va réveiller le troisième thread, mais il ne peut pas prendre le mutex immédiatement. L’un des autres auteurs peut prendre le mutex en premier. Cependant, vous pouvez obtenir ce que vous voulez avec un peu plus de travail:

 void put(int *p) { pthread_mutex_lock(&mutex); while (variable) pthread_cond_wait(&cond_empty, &mutex); variable = p; pthread_cond_signal(&cond_full); pthread_mutex_unlock(&mutex); } int *get() { int *ret; pthread_mutex_lock(&mutex); while (!variable) pthread_cond_wait(&cond_full, &mutex); ret = variable; variable = NULL; pthread_cond_signal(&cond_empty); pthread_mutex_unlock(&mutex); return ret; } 

En attendant explicitement que la variable soit lue, nous évitons la condition de concurrence potentielle.

Voici ce que j’ai trouvé dans la norme :

4.13 Politique de planification

Une stratégie de planification affecte l’ordre des processus ou des threads:

[…]

  • Lorsqu’un processus ou un thread est un thread bloqué et qu’il devient un thread exécutable

Les implémentations conformes doivent définir la manière dont chacune des politiques d’ordonnancement peut modifier les priorités ou affecter autrement l’ordre des processus ou des processus dans chacune des occurrences énumérées ci-dessus. De plus, les implémentations conformes doivent définir dans quelles autres circonstances et de quelle manière chaque politique de planification peut modifier les priorités ou affecter l’ordre des processus ou des processus.

Donc, c’est apparemment non défini. Ce n’est pas surprenant: en règle générale, vous ne pouvez rien supposer sur le thread exécutable qui doit être exécuté.

Selon la page de manuel pthread_cond_wait

Le ou les threads débloqués doivent se battre pour le mutex conformément à la politique de planification (le cas échéant) et comme si chacun d’entre eux avait appelé pthread_mutex_lock ().

Malheureusement, autant que je sache, il n’y a pas de politique de planification disponible qui vous donne le comportement que vous souhaitez.