Unerwartete Ausgabe in einem Multithread-Programm

8

Es folgt ein Programm, das Pthreads verwendet.

%Vor%

Jedes Mal, wenn ich das Programm ausführe, erwarte ich eine unterschiedliche Anzahl von Ausführungsnummern aus dem Haupt-Thread und dem Unter-Thread (weil der Haupt-Thread möglicherweise vor dem Kind beendet wird). Ich bekomme diese erwartete Ausgabe manchmal. Aber ich habe eine Ausgabe wie folgt, die ich nicht verstehe warum.

%Vor%

Warum haben die Beispielthreads 0 und 4 zweimal gedruckt?

    
DesirePRG 06.10.2014, 07:14
quelle

1 Antwort

8

Wie von @R .. in den Kommentaren hervorgehoben, scheint dies ein Fehler in der Implementierung von glibc (vorausgesetzt, Sie verwenden Linux - ich kann dies auf Linux 2.17 reproduzieren, das mit GCC 4.9.1 kompiliert wurde), da exit() nicht sicherstellt, dass während des Flushens und Schließens von Streams kein Rennen stattfindet, wenn es von einem aufgerufen wird Thread, wenn mehrere Threads stdout verwenden.

Der folgende Code von flockfile zeigt deutlich an, dass das beobachtete Verhalten nicht korrekt ist:

  

Die stdio-Funktionen sind Thread-sicher. Dies wird erreicht durch   Zuweisen eines Lockcounts zu jedem FILE-Objekt und (wenn der Lockcount ist   nicht Null) ein Eigenthread. Für jeden Bibliotheksaufruf diese Funktionen   Warten Sie, bis das FILE-Objekt nicht mehr von einem anderen gesperrt ist   thread, dann sperren Sie es, führen Sie die angeforderte E / A, und entsperren Sie das Objekt   wieder.

Angesichts dieser Tatsache können die folgenden Optionen als Problemumgehung (da es keine Antwort auf den Fehlerbericht gibt) für diesen speziellen Fall, den wir hier beobachtet haben, betrachtet werden.

Beide Threads "teilen" den stdout -Stream und ich denke, die "extra" -Ausgabe wird wegen des vorzeitigen Ausgangs des Hauptthreads gedruckt.

printf buffers (in sample_thread() ) die Ausgabe und bevor sie den Puffer löschen konnte (aufgrund von \n in printfs), wird der Hauptthread beendet. Daher erzwingen Sie den Flush von stdout buffer, wenn der Prozess beendet wird.

Um zu beheben,

1) Sie könnten setbuf() in main() vor dem Erstellen des Threads aufrufen:

%Vor%

bis nicht Puffer stdout überhaupt.

oder
2) Rufen Sie in beiden Threads pthread_exit() auf, damit der Prozess fortgesetzt wird, wenn einer der beiden Threads stirbt.

oder
3) Rufen Sie pthread_join() im Hauptthread auf, so dass der Hauptthread auf den Abschluss von sample_thread thread wartet.

Einer davon wird das Problem vermeiden.

    
P.P. 06.10.2014, 07:38
quelle

Tags und Links