Question

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 le troisième en cours d'exécution:

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 pourrait l'être? attendre sur la serrure?

Était-ce utile?

La solution

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);

Rien ne garantit 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.

Autres conseils

Voici ce que j'ai trouvé dans le standard :

  

4.13 Politique de planification

     

Une stratégie de planification affecte le processus ou l'ordre 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 autrement affecter l'ordre des processus ou des threads à chacune des occurrences énumérées ci-dessus. En outre, les implémentations conformes doivent définir dans quelles autres circonstances et de quelle manière chaque règle de planification peut modifier les priorités ou affecter l’ordre des processus ou des tâches.

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 disputer 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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top