Sleep(1)
-
Jochen Kalmbach schrieb:
#include <windows.h> #include <tchar.h> int _tmain(void) { while(true) { Sleep(0); } }
=> 100% CPU Auslastung (bei 1-Prozessor-System).
Wir reden hier aber schon über WinAPI und nicht Konsole, oder? Eine WinAPI Anwendung mit Sleep(0) hat jedenfalls keine 100% CPU Auslastung, da kannst du dich noch so quer stellen, das _ist_ so. Und was ihr mit eueren Prioritäten habt, ist mir auch unklar. Darum geht es überhaupt nicht. Alles was ich gesagt habe, ist, dass wer Sleep(1) verwendet, genauso gut Sleep(0) verwenden kann. Da ändert auch nichts daran, dass durch Sleep uU Probleme entstehen können. Denn dann sind sie in beiden Fällen vorhanden.
Und zum Thema Deadlock: so weit ich weiss, können diese hier nur entstehen, wenn es zwischen dem Thread mit höherer Priorität und dem Thread mit niedrigerer Priorität eine Abhängigkeit gibt, zB weil der eine auf den anderen wartet. Aber dass für solche Geschichten sowieso entsprechende Synchronisationsobjekte (Event, Mutex, Semaphore, etc.pp) verwendet werden sollte, hatten wir ja längst geklärt. Also regt euch mal nicht so künstlich auf und erzählt von Sachen, die sowieso nie zur Diskussion standen.@Jochen
Das mit dem Buch war wohl ein Scherz, oder?
-
groovemaster schrieb:
Wir reden hier aber schon über WinAPI und nicht Konsole, oder? Eine WinAPI Anwendung mit Sleep(0) hat jedenfalls keine 100% CPU Auslastung, da kannst du dich noch so quer stellen, das _ist_ so.
Dann solltest Du es ganz dringend mal ausprobieren... oder hier mal ein komplettes Beispiel posten!
Console oder WinApp spielt für den Scheduler keine Rolle... davon kennt der nix...
#include <windows.h> #include <tchar.h> int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) //int _tmain(void) { while(true) { Sleep(0); } }
groovemaster schrieb:
Alles was ich gesagt habe, ist, dass wer Sleep(1) verwendet, genauso gut Sleep(0) verwenden kann.
Und das ist absolut falsch, da die Änderung des Parameters von 0 auf >0 eine massiven Unterschied macht!
(Sleep(1) macht nämlich genau das was Du denkst, was Sleep(0) machen würde!)
-
@Jochen Kalmbach:
Wie siehts eigentlich mit SwitchToThread aus? Die Doku ist da ja nicht sonderlich klar, liest sich für mich aber so als ob da auch Threads mit niedrigerer Priorität drankommen würden.Kann man SwitchToThread reinen Gewissens für Spinlocks verwenden?
-
SwitchToThread hat prinzipiell den gleichen Effekt wie Sleep(0).
PS: Ein Sleep/SwitchToThread macht i.d.R. fast nie Sinn. Synchronisationen sollte man immer über Events/Semaphore/Interlockes machen...
-
Sorry das ich mich da jetzt mal so 'reinschiebe', aber hab da auch mal ne kleine Frage...:
Ich verwende Sleep(n) (n mindestens > 100) um die Laufzeit meines Programms zuverbessern. Eini Thread meines Programms hat einen rechenintensiven Vorgang zu bewältigen, der sich vom Benutzer pausieren lässt, das ist so realisiert:// ... // in der Thread-Prozedur: // ... while(pThreadData->fPaused) // Variable ist volatile und wurde als Datenstruktur an den Thread übergeben (fPaused ist vom Typ bool) Sleep(100); // ...
Ist das sinnvoll ? Damit dürfte doch mehr Rechenzeit für andere Prozesse/Threads zur Verfügung stehen, oder?
(Hab mir nicht den gesamten Forum-Thread durchgelesen. )
-
CodeFinder schrieb:
Ist das sinnvoll ?
nö, nicht wirklich. nimm besser 'WaitForSingleObject()' für solche verschnaufpausen...
-
Ne, wirklich sinnvoll ist das nicht. Nimm lieber einen Event, auf den du mit WaitForSingleObject() warten kannst.
-
net schrieb:
CodeFinder schrieb:
Ist das sinnvoll ?
nö, nicht wirklich. nimm besser 'WaitForSingleObject()' für solche verschnaufpausen...
Huh?!, Aber worauf soll ich denn dann warten...auf den Haupthread ?
-
CodeFinder schrieb:
Huh?!, Aber worauf soll ich denn dann warten...?
auf was du willst. guckst du CStoll's posting...
-
Hm ok, verstehe ... ist nur irgendwie mehr Aufwand, ...aber danke .
-
CodeFinder schrieb:
net schrieb:
CodeFinder schrieb:
Ist das sinnvoll ?
nö, nicht wirklich. nimm besser 'WaitForSingleObject()' für solche verschnaufpausen...
Huh?!, Aber worauf soll ich denn dann warten...auf den Haupthread ?
Nein, auf einen Event, der ausgelöst wird, wenn der Nutzer den Pause-Modus beendet.
-
CStoll schrieb:
[...]Nein, auf einen Event, der ausgelöst wird, wenn der Nutzer den Pause-Modus beendet.
Jo und das wird im Hauptthread gesetzt, das meinte ich damit .
-
Jochen Kalmbach schrieb:
PS: Ein Sleep/SwitchToThread macht i.d.R. fast nie Sinn. Synchronisationen sollte man immer über Events/Semaphore/Interlockes machen...
Jo, das ist mir schon klar, danke
Es gibt halt Fälle wo man - weils manchmal einfacher ist - interlocked variablen pollt. Und in so einer Schleife macht dann ein Sleep(1) schon Sinn... bei einem spin-sleep-lock ala critical section isses natürlich wurscht, da spinnt man ja eh nicht lange.
-
_msg schrieb:
Zitat:
Nö, Sleep(0) ist nicht böse.
Sleep ist vielleicht nicht böse - aber die häufige Verwendung dieser Funktion deutet zumindest auf Faulheit oder mangelnde Kenntnisse beim Programmieren hin. Sleep wird gerne eingesetzt, wenn Threads Ergebnisse pollen sollen und der Programmierer sich an Signalisierungsobjekte und Wartefunktionen nicht herantraut.Wer Threads und Signale sinnvoll einsetzt, benötigt kein Sleep.
---
CodeFinder schrieb:
Hm ok, verstehe ... ist nur irgendwie mehr Aufwand, ...aber danke .
q.e.d
-
@CodeFinder: Kannst Du Dich mal bei mir per Mail melden!?
-
-
CodeFinder schrieb:
Jochen Kalmbach schrieb:
@CodeFinder: Kannst Du Dich mal bei mir per Mail melden!?
Huh?!, why ?
Wird dann verraten wenn Du es machst (ist aber nix schlimmes)
-
Jups habsch gemacht, hoffe sie ist angekommen.
-
Jochen Kalmbach schrieb:
hustbaer schrieb:
Von daher ist Sleep(0) an den Stellen wo man es üblicherweise findet (spinlock, polling) "böse" weil es Threads mit niedrigerer Priorität sämtliche CPU Zeit klaut.
Es ist nicht nur unsauberer Code, sondern wirklich böse!!!
Was man damit heraufbeschwört ist das sog. "Priority Inversion"!
http://en.wikipedia.org/wiki/Priority_inversionFolgendes Szenario:
Ein Thread mit Prio 11 wartet auf eine Resource (z.B. Event), welcher von einem Thread mit Prio 4 gerade gehalten wird.
Nun gibt es den Thread von "groovemaster" mit Prio 7, welcher ein "Sleep(0)" eingebaut hat und gerade anfängt zu laufen.
Was passiert:
Der Thread mit Prio 4 wird nie wieder drankommen und somit wird auch der Thread mit Prio 11 blokiert.
Fazit: Wir haben sozusagen einen "Dead-Lock", der von groovemaster verursacht wurde!(ok, das Windows-OS hat für einen solchen Fall im dnymaischen Prio-Bereich auch eine akzeptable Lösung... wer kennt sie?)
War vielleicht groovemaster an der Software-Entwicklung für den "Mars Pathfinder" beteiligt!? Da ist nämlich genau das passiert
Falls es noch wen interessiert (habs grad erst gelesen):
Für den von dir beschriebenen 'Dead-Lock' existiert unter NT-basierten Systemen ein Systemthread aus der Speicherverwaltung (kenne den unter der deutschen Bezeichnung 'Systemausgleichthread' ), welcher jede Sekunde prüft, ob ein Thread bereits seit mehr als 4 Sekunden nicht mehr an der Reihe war. Wenn er einen findet, setzt er die dynamische Priorität des betreffenden Threads auf einen höheren Wert (glaube auf 18). Aber das macht er pro Suchlauf nur bei maximal 10 Threads. Sollte es noch mehr davon geben, dann bricht er den Suchlauf ab um ihn eben eine Sekunde später an der gleichen Stelle fortzusetzen und weitere Threads aufzusuchen. Vielleicht nicht der Weisheit letzter Schluss,aber es funktioniert anscheinend ganz gut.grüsse
-
Mir ist jetzt (gestern) auch was passiert, müsste auch zum Thema passen:
Ein Programm von mir entpackt oggs, Dauer noch ca. 1 Stunde
Naja, damit es schneller geht, hab ich im Task-Manager die Prio des Prozesses (womit ja auch automatisch die Thread-Prio steigt) hochgehoben.Dachte erst, im Explorer geht nichts mehr (Prio Normal). Aber ging doch, nur etwas langsam... Reaktionszeit 4 Sekunden könnte hinkommen
Naja, jedenfalls ist es wohl, anders als ständig behauptet, nicht der Fall, dass Threads mit niedriger Priorität nie drankommen.