2 Stimmen

Garantierte Nachgiebigkeit mit pthread_cond_wait und pthread_cond_signal

Angenommen, ich habe ein C-Programm mit 3 POSIX-Threads, die sich eine globale Variable, einen Mutex und eine Bedingungsvariable teilen, von denen zwei den folgenden Psuedocode ausführen:

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

Und das dritte Rennen:

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

Kann man davon ausgehen, dass der dritte Thread die Daten aus den ersten beiden Threads sehen wird?

Anders ausgedrückt: Wenn ein Thread auf einen Mutex und eine Bedingungsvariable wartet, kann man dann davon ausgehen, dass er der nächste ist, der die Sperre erhält, wenn sie signalisiert wird, und nicht ein anderer Thread, der möglicherweise auf die Sperre wartet?

12voto

bdonlan Punkte 213545

So etwas wie pthread_mutex_wait gibt es nicht. Ich nehme an, Sie meinen:

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

Es gibt keine Garantie dafür, dass der dritte Thread die Daten von beiden sieht. pthread_cond_signal weckt den dritten Thread, aber er nimmt den Mutex möglicherweise nicht sofort. Einer der anderen Writer könnte den Mutex zuerst übernehmen. Mit etwas mehr Arbeit können Sie jedoch erreichen, was Sie wollen:

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

Indem wir explizit darauf warten, dass die Variable gelesen wird, vermeiden wir eine mögliche Race Condition.

1voto

Bastien Léonard Punkte 57728

Das habe ich in der Standard :

4.13 Terminplanungspolitik

Eine Scheduling-Policy beeinflusst die Prozess- oder Threadreihenfolge:

[...]

  • Wenn ein Prozess oder Thread ein blockierter Thread ist und ein lauffähiger Thread wird

Konforme Implementierungen müssen die Art und Weise definieren, in der jede der Planungsrichtlinien die Prioritäten ändern oder die Reihenfolge der Prozesse oder Threads bei jedem der oben aufgeführten Ereignisse anderweitig beeinflussen kann. Darüber hinaus müssen konforme Implementierungen festlegen, unter welchen anderen Umständen und auf welche Weise jede Planungsrichtlinie die Prioritäten ändern oder die Reihenfolge von Prozessen oder Threads beeinflussen kann.

Sie ist also offensichtlich nicht definiert. Das ist nicht überraschend: Im Allgemeinen kann man nicht davon ausgehen, dass ein lauffähiger Thread für die Ausführung vorgesehen ist.

0voto

Tyler McHenry Punkte 71707

Nach Angaben der pthread_cond_wait Manpage

Der/die Thread(s), der/die nicht blockiert ist/sind, konkurriert/konkurrieren um die Mutex gemäß der Scheduling-Policy (falls zutreffend) und so, als hätte jeder pthread_mutex_lock ().

Soweit ich das beurteilen kann, gibt es leider keine verfügbare Planungsrichtlinie, die das gewünschte Verhalten ermöglicht.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X