PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Multithreading: Events sind generell gefährlich?


zeckensack
2005-06-09, 01:31:12
"Yet both respected computer science researchers and experienced multithreading practitioners believe event variables are so inherently error-prone that they should never be used, and thus should not be part of a multithreading library."
<...>
"event operations force the programmer to be aware of the relative speeds of the sending and receiving processes"

Darüber bin ich hier (http://boost.sourceforge.net/doc/html/threads/rationale.html#threads.rationale.events) gestolpert. Nur macht mich das als Erklärung nicht so recht satt. Da gibt's auch irgendwo noch einen Bibliographie-Verweis zum weiterlesen, aber der läuft ins leere :|

Kann mir das jemand kurz und knackig erklären?

Pinoccio
2005-06-09, 01:44:26
Könntest du einem völlig Unwissenden ... jaja, ich bin ja schon ruhig.

(scnr (http://www.forum-3dcenter.org/vbulletin/showthread.php?t=226849))
mfg Sebastian

Demirug
2005-06-09, 09:18:11
Das ganze hat etwas mit der Semantik des Begriffs Event zu tun.

Der Definition von Brinch Hansen folgenden kennt ein Event nur die Threads welche auf das Signal warten. Also eine einfache Liste mit Threads. Ruft ein Thread die entsprechenden wait Operation auf hängt er sich selbst in diese Liste ein und setzt sich in den warte Zustand. Ein Aufruf der signal Operation nimmt nun einen oder alle Threads in der Liste (abhängig von den Aufrufparameter) und setzt dieses Threads wieder in Ready Zustand. Die betroffenen Threads werden aus der Liste des Event Objekts gelöscht.

Das Problem mit dieser Implemetierung ("event variables of the previous type")ist schnell offensichtlich. Ruft Thread A signal auf before Thread B wait aufgerufen hat ist das Signal verloren und Thread B wartet endloss. Das sind die "hidden timing dependencies" von denen in dem Text gesprochen wird.

Die Events in Windows sind nun allerdings anders implementiert. Diese enthalten zusätzlich zu der Brinch Hansen Variante ein Zustandflag. Dadurch kann ein Event von Thread A mit SetEvent in den signalisierten Zustand versetzt werden welcher dann dazu führt das ein zeitlich später erfolgter WaitForSignalObject in Thread B den Thread nicht blockiert und endloss wartet. Ist das Event zum Zeitpunkt von WaitForSignalObject nicht signalisiert läuft das ganze dagegen fast genauso ab wie bei Brinch Hansen. Ob das Event sich danach immer noch im signalisierten Zustand befindet hängt davon ab ob es sich um ein Manuelles oder AutoReset Event handelt.

Der Verweiss auf die "Experienced programmers using the Windows platform today" erscheint mir etwas deplaziert. Ich vermute diese Personen hatten eher algemeine Problem was das Multithreading angeht oder sie haben die PulseEvent Funktion benutzt. Diese simuliert aus Kompatibilitätsgründen nämlich genau das Verhalten das man von den Brinch Hansen Events kennt. Aber deswegen findet man in der Dokumenation ja auch extra eine Warnung: "This function is unreliable and should not be used".

zeckensack
2005-06-09, 13:06:44
Alles klar, danke :)

zeckensack
2005-06-09, 14:20:39
Könntest du einem völlig Unwissenden ... jaja, ich bin ja schon ruhig.

(scnr (http://www.forum-3dcenter.org/vbulletin/showthread.php?t=226849))
mfg SebastianEvents sind eine Spezies der Gattung der Synchronisationsobjekte.
Dabei handelt es sich um Datentypen, die man nutzen kann/soll, um in Software mit mehreren Threads
a)kleinere Kommunikationsaufgaben zwischen den Threads abzuwickeln, und
b)in Momenten wo es keinen Sinn hat dass mehrere Threads gleichzeitig laufen (Thread A wartet auf Antwort von Thread B oder Thread B muss erst eine Aufgabe beendet haben, damit Thread A sinnvoll weiterarbeiten kann, bzw umgekehrt), diese zu serialisieren.

Beispiel:HEVENT feuerwehrwagen_frei;
HEVENT brauche_feuerwehr;
HEVENT muss_löschen;
HEVENT erfolgreich_gelöscht;
beginthread(FeuerwehrwagenThread);
beginthread(FeuerwehrDienststellenThread);
beginthread(HausThread);

HausThread()
{
while(1)
{
if (es_brennt)
{
SignalEvent(haus_braucht_feuerwehr);
//warten bis das Feuer gelöscht wurde
WaitForSingleObject(erfolgreich_gelöscht);
ResetEvent(haus_braucht_feuerwehr);
}
lass_den_efeu_wuchern();
}
}

FeuerwehrDienststellenThread()
{
while (1)
{
//warte bis der Feuerwehrwagen frei ist
WaitForSingleObject(feuerwehrwagen_frei);
//warte bis es was zu tun gibt
WaitForSingleObject(haus_braucht_feuerwehr);
ResetEvent(feuerwehrwagen_frei); //jetzt nimmer
ResetEvent(erfolgreich_gelöscht);
SetEvent(muss_löschen);
}
}

FeuerwehrWagenThread()
{
while (1)
{
//warte bis es was zu tun gibt
WaitForSingleObject(muss_löschen);
fahre_zu_haus();
lösche();
ResetEvent(muss_löschen);
SetEvent(erfolgreich_gelöscht);
SetEvent(feuerwehrwagen_frei);
}
}Oder so ähnlich X-D

Gast
2005-06-09, 20:01:44
Events sind eine Spezies der Gattung der Synchronisationsobjekte.
Dabei handelt es sich um Datentypen, die man nutzen kann/soll, um in Software mit mehreren Threads [...]



Geil, made my day. Schon mal daran gedacht ein programmierbuch zu schreiben? :D