Problem mit Threads
-
Hallo ich hätte mal ein paar Fragen zu Threads, bzw. etwas genauer zu einem Programm das ich geschrieben habe.
Am Anfang werden zwei Threads erstellt. Es soll nun jeder der beiden Threads darauf warten bis der andere eine gewisse aktion ausgeführt hat, dass funktioniert über zwei bool Variablen die global definiert sind.
funktionsweise:
Thread_1 setzt _bool1 auf true und wartet danach bis _bool2 auf true ist.
while(run) { _bool1 = true; i++; while(!_bool2) { } _bool2 = false; }Thread_2 wartet bis _bool1 auf true ist und schaltet dann _bool2 auf true und _bool1 auf false
while(run) { while(!_bool1) { } i++; _bool1 = false; _bool2 = true; }Das Hauptprogramm bricht jetzt nach einer Sekunde das ganze wieder ab(run auf false) und jeder Thread gibt an wie oft er ausgeführt wurde(über die lokale Variable i)
Das Programm funktioniert auch recht gut nur irgendwie sehr langsam.
Nach einer Sekunde habe ich bei beiden nur 30-40 durchläufe!Habe beide mal ohne das Warten laufen lassen:
while(run) { i++; }und kommme dabei auf astronomische Zahlen. Kann es sien das es etwas mit dem Schreiben und Lesen auf die globalen Variablen zu tun hat, das das ganze so langsam wird.
Ich hab leider von der Thread Programmierung noch so gut wie keine Ahnung,wäre also schön wenn mir einer helfen könnte.
-
aua, aua, aua
Sieh dir unbeding mal was zum thema thread snychronisation und locking an.
Dir ist schon klar das dein thread, während er wartet, auf volldampf in die nichts-machende while schleife abarbaitet, was unmenden CPU zeit frisst?2. Problem:
- Thread 1 hat rechenzeit: lade i aus dem RAM (wert 0)
- Thread 2 hat rechenzeit: lade i aus dem RAM (wert 0)
- Thread 1 hat rechenzeit: i wird inkerementiert und zurück geschrieben (wert 1)
- Thread 2 hat rechenzeit: i wird inkerementiert und zurück geschrieben (wert 1)
Du jetzt 2 mal i++ gemacht aber im ram steht der wert 13. Problem:
Ist _bool1/_bool2 als volatile deklariert?
Falls nicht kann dir sehr leicht das passieren:
- Thread 1 hat rechenzeit: lade _bool2 in ein CPU reigster.
- Thread 2 bekommt rechenzeit: CPU register von thread 1 werden gesichter
- Thread 2 setzt _bool2 auf true (wird ins ram geschriebe)
- Thread 1 bekommt rechenzeit: CPU register von thread 1 werden wieder zurück geladen
- ist das CPU reigster mit _bool2 true? Nö.
- Thread 2 bekommt rechenzeit: ...
-
Danke für die Antwort, hat schon was geholfen. Kann man die Beriche mit CriticalSections absichern bei denen auf die Variablen zugegriffen wird?
Noch ne Frage zu volatile: was macht das jetzt wieder ganz genau, kann mich nur noch bruchteilhaft daran errinern?
Gibt es eine Möglichkeit einen Thread, z.B. wenn ein eine Variable, in dem Falle eine bool, nicht den entsprechenden Wert hat wieder die Rechenzeit zu entziehen, so das er die CPU nicht mer auslastet? Am besten direkt aus dem Thread selbst.
Gibt es sonst noch eine elegante Art zwischen Threads Informationen auszutauschen z.B. irgendwelche Nachrichten zu schicken wie Mache dies oder das?
Damit meine ich jetzt nicht die pipes.
-
Schau dich mal hier ein wenig um

Lx386 schrieb:
Gibt es eine Möglichkeit einen Thread, z.B. wenn ein eine Variable, in dem Falle eine bool, nicht den entsprechenden Wert hat wieder die Rechenzeit zu entziehen, so das er die CPU nicht mer auslastet? Am besten direkt aus dem Thread selbst.
Das könntest du z.B. über ein Event machen, auf das du mit WaitForSingleObject wartest

-
Wie muss ich den das mit WaitForSingleObject genau machen?
Ist es nicht möglich mit einer Funktion die aktuelle rechenzeit die der Thread besitzt vorzeitig zu pausieren(dh. einen anderen Thread die Rechenzeit wieder geben).
-
Sleep(0) bzw. SwitchToThread
-
Wie muss ich den das mit WaitForSingleObject genau machen?
Eretzte das bool duch ein HANDLE und erzeuge die 2 events mit CreateEvent(NULL,FALSE,TRUE/FALSE,NULL) (TRUE/FALSE ja nachdem ob das event beim erstemm schon auf singaled gesetzt werden soll.
Dann mach aus der while ein WaitForSingleObject(hEvent,INFINITE) und auf dem _bool ein SetEvent. FertigDas volatle sorgt dafür, dass der wert jedes mal aus der ram kommt und nich in nem cpu register liegen bleibt
-
Danke für die Antworten!
Hat mir super geholfen!Hab in der Zwischenzeit mal in die MSDN reingeschaut und das ganze mit SwitchToThread() ausprobiert funktioniert echt super.
meine Schleife im Thread sieht jetzt folgendermasen aus:
while(!_bool1) { SwitchToThread(); }Ist da was gegen einzuwenden das so zu machen? Oder wär das mit WaitForSingleObject besser?
-
Oder wär das mit WaitForSingleObject besser?
bestimmt