Anfängerfrage zu Multithreading
-
Hallo,
ich habe da mal ein paar kleine Fragen zum Thema Multithreading.
Zum Spielen nutze ich folgenden Code:
#include <iostream> #include <thread> using namespace std; void CoutZahl () { for (int i=0; i<10;i++) { cout << i << endl; } } int main () { thread COUT (CoutZahl); COUT.join(); cout << "Hallo Hallo"; return 0; }So, wie dargestellt, gibt er mir die Zahlen 0 bis 9 gefolgt von "Hallo Hallo" aus.
Wenn ich das "COUT.join" auskommentiere gibt er mit zuerst "terminate called without an active exception" aus und dann "Hallo Hallo".
Wieso ist das so, dass hier keine Zahlen auftauchen?
Liegt es daran, dass beide Threads dann gleichzeitig auf die Konsole zugreifen wollen?Und mal als generelle Frage, wie schaffe ich es einen Thread zu erstellen, der permanent parallel ausgeführt wird. Ich habe z.B. eine Endlosschleife, die in einem Thread immer laufen soll und nebenbei soll der Hauptthread abgearbeitet werden (mehrere Prozessorkerne sind vorhanden).
Vielen Dank

-
Antwort zum fehlenden join:
Wenn ein Thread seinen Gültigkeitsbereich verlässt, bevor er gejoined wurde (obwohl er joinbar wäre), dann wird terminate aufgerufen. Das ist so ziemlich der härtest mögliche Weg, ein Programm abzubrechen. Keine Ressourcen werden freigegeben, Streams werden nicht synchronisiert. Das heißt, das einzige, was da eventuell noch ausgegeben wird ist das, was es bis dahin zufällig noch in die Ausgabe geschafft hat.Zugriff auf das cout-Objekt aus mehreren Threads ist im übrigen nicht threadsicher, in dem Sinne, dass du dadurch zwar nicht den Stream beschädigen kannst, aber die Ausgabe ist nicht synchronisiert. Das heißt, du könntest bei deinem Beispielprogramm (wenn du join nach dem
cout << "Hallo Hallo"machen würdest) als Ergebnis irgendwelchen Müll wie0 H1 all2 o 3 ...bekommen. Manche Compiler bieten als Feature synchronisierte Ausgabefunktionen an (z.B. GCC, wenn man printf benutzt), aber im allgemeinen muss man sich selber darum kümmern.
Zur Frage mit der Endlosschleife:
Einfach machen. Wo ist das Problem?
-
Vielen Dank für die Antwort.
Das mit der Endlosschleife hat sich geklärt.
Ich weiß nun warum es bei mir nicht geht.
Ich nutze QT Bibliotheken und die verhindern anscheinend das Verschieben von bestimmten Prozessten in die Threads.
Anstatt <thread> müsste ich wohl <QThread> nutzen, aber mich in die eigene QT-Sprache einzuarbeiten, schaffe ich momentan zeitlich nicht
Die ganzen QT Bibliotheken sind ja wie eine eigene Programmiersprache...
Zu dem fehlenden Join:
Mir ist noch immer nicht ganz klar, warum der Thread seinen Gültikeitsbereich verlässt bzw. wie dieser definiert ist.
-
Britzi schrieb:
Mir ist noch immer nicht ganz klar, warum der Thread seinen Gültikeitsbereich verlässt bzw. wie dieser definiert ist.
Aber du weißt, was Gültigkeitsbereiche sind? (Falls nicht -> Jetzt sofort angucken. Ganz wichtige Grundlage!) Der Thread ist auch nur eine ganz normale Variable (zumindest von der Programmlogik her) und in diesem Fall endet ihre Gültigkeit eben mit dem return aus der main. Aber der Destruktor eines Threads ruft eben kein stilles join auf*, sondern eben stattdessen abort, wenn der Thread nicht richtig gejoined wurde.
*: Aus Gründen. Zum Beispiel was passiert, wenn der Thread in einer Endlosschleife steckt.
-
Alles klar, ich habs verstanden, glaub ich zumindest.

Was Gültigkeitsbereiche sind, weiß ich.
Mir war nur nicht bewusst, dass die Threads von der Main abhängen, aber das ist ja logisch.Das return in der main beendet die Gültigkeit des Threads mit einem abrupten Abbruch.
Um dies zu verhindern muss die Main solange warten bis der Thread beendet ist.
Dies geht durch das .join()Richtig?
Danke

-
SeppJ schrieb:
*: Aus Gründen. Zum Beispiel was passiert, wenn der Thread in einer Endlosschleife steckt.
Dann hat man ein fehlerhaftes Programm. Das ist kein Grund gegen ein stilles join().
-
unbegründet schrieb:
SeppJ schrieb:
*: Aus Gründen. Zum Beispiel was passiert, wenn der Thread in einer Endlosschleife steckt.
Dann hat man ein fehlerhaftes Programm. Das ist kein Grund gegen ein stilles join().
Und? Ist das ein Grund für ein stilles join()?
-
unbegründet schrieb:
SeppJ schrieb:
*: Aus Gründen. Zum Beispiel was passiert, wenn der Thread in einer Endlosschleife steckt.
Dann hat man ein fehlerhaftes Programm. Das ist kein Grund gegen ein stilles join().
Die beiden Aussagen widersprechen sich. Wenn ein Programm fehlerhaft ist: Let it crash! Wem auf der Welt wird denn jemals geholfen, wenn man still und heimlich den Fehler vertuscht?
-
Ob man ein implizites
joinmachen soll war nie die Frage - das wäre das dämlichste was man machen könnte. Würde nur Probleme verursachen.
Die Frage war: implizitesdetachoder implizitesabort?Und da man mit implizitem
aborteinige Fehler aufdeckt die mit implizitemdetachnich auffallen würden, und man dasdetachja falls erwünscht jeder zeit selbst machen kann, hat man sich fürabortentschieden.
MMn. eine ziemlich klare Sache.Das einzig doofe dabei ist dass Boost.Thread es ursprünglich anders gemacht hat, und daher alle Programme angepasst werden mussten/müssen die Boost.Thread verwenden.