Thread zum aktualisieren
-
Unix-Tom schrieb:
Ich wollte lediglich nicht die Aussage stehen lassen das man von einem Thread nicht ein Control der GUI ändern kann. Es geht auch wenn es in vielen Fällen nicht notwedig ist und in manchen Fällen nicht anders geht.
Es geht viel auch wenn es nicht unbedingt schlau/sicher ist.
Sicher ist imho nur PostMessage an den Besitzer der control.
-
Wenn man mit Threads arbeitet muss mann sowieso Sync einbauen.
Ich sagte nicht das es schlau ist einfach ein Control zu ändern ohne darauf zu schauien das dies kein anderer zur gleichen Zeit macht.
-
Unix-Tom schrieb:
Wenn man mit Threads arbeitet muss mann sowieso Sync einbauen.
Ich sagte nicht das es schlau ist einfach ein Control zu ändern ohne darauf zu schauien das dies kein anderer zur gleichen Zeit macht.flounder schrieb:
The Best Synchronization Is No Synchronization: Alternatives to semaphores, mutexes, and CRITICAL_SECTIONs
-
@Unix-Tom: Ich wiederhole meine Frage: wie willst du verhindern dass das Control gezeichnet wird, während der Worker-Thread darauf zugreift?
-
EOP schrieb:
Der erste Absatz (nach der Einleitung) in dem Artikel ist gefährlicher Bullshit. Der Author schein zwar nicht gerade eine Vollvase zu sein, aber dennoch schreibt er da (zumindest) im Absatz "When it isn't needed at all" totalen Topfen.
Auf x86 CPUs mag das so funktionieren, aber als allgemein gültige Aussage ist es einfach nur falsch.
p.S.: das warum ist leider etwas schwer zu erklären. Im Prinzip geht es um die Sichtbarkeit von Änderungen, bzw. allgemeiner: darum was einem ein bestimmtes Speichermodell garantiert, und nicht garantiert. Und ganz allgemein kann man einfach nicht davon ausgehen, dass das Schreiben einer volatile Variable "release" Semantik hätte, bzw. das Lesen einer volatile Variable "acquire" Semantik.
-
hustbaer schrieb:
EOP schrieb:
Der erste Absatz (nach der Einleitung) in dem Artikel ist gefährlicher Bullshit. Der Author schein zwar nicht gerade eine Vollvase zu sein, aber dennoch schreibt er da (zumindest) im Absatz "When it isn't needed at all" totalen Topfen.
Was stört dich so. Mit der Angabe von volatile sollte man doch aus dem schneider sein, oder?
Was stört Dich an diesem ersten Absatz?BTW: Josef ist ein schräger Vogel... ich hatte das Vergnügen ihn kennen zu lernen und bin ein paarmal in senem "privat Taxi" mit gefahren.
-
Josef schrieb:
But it is important to realize that the hardware provides synchronization on 32-bit scalar values implicitly, so an operation that merely stores a value which does not depend on any previous state of the variable does not require synchronization.
Kann das jemand bestätigen? Da war ich mir immer unsicher und so explizit habe ich das noch nirgends gelesen.
-
Das ist so. Zumindest für x86, wie das die 64bit Prozessoren handhaben weiß nicht nicht sicher. Minimum ist auch hier 32bit.
Ein Problem taucht hier aber schon auf, wenn man Strukturen hat und z.B. Daten packt. Wichtig ist eben das das Aligment auch stimmt.
Sonst kann aus einen bool Zugriff schnell eine nicht atomare Zuweisung werden.Genauso problematisch kann der Zugriff auf einen BYTE Array sein... so etwas ist nicht atomar...
-
Sehr gut, danke! Das hilft mir wirklich weiter

-
Martin Richter schrieb:
hustbaer schrieb:
EOP schrieb:
Der erste Absatz (nach der Einleitung) in dem Artikel ist gefährlicher Bullshit. Der Author schein zwar nicht gerade eine Vollvase zu sein, aber dennoch schreibt er da (zumindest) im Absatz "When it isn't needed at all" totalen Topfen.
Was stört dich so. Mit der Angabe von volatile sollte man doch aus dem schneider sein, oder?
Was stört Dich an diesem ersten Absatz?Bei x86 ja, weil x86 ein sehr "nettes" Speichermodell vorschreibt.
Andere CPUs, wie z.B. Itanium, DEC Alpha, Power PC etc. verhalten sich da ganz anders. Bei denen können lustige Dinge passieren...
int a = 0; int volatile b = 0; void foo() { a = 1; // hier fehlt eine memory-barrier b = 1; } int main() { start_foo_thread(); while (b == 0); // hier fehlt auch eine memory-barrier printf("a: %d\n", a); }Auf einer x86 Plattform wirst du hier immer 1 bekommen. Auf anderen CPUs nicht unbedingt, da andere CPUs z.T. reordering machen, die Caches nicht kohärent halten etc.
p.S.: es würde auch nix helfen a hier zusätzlich volatile zu machen.
p.p.S.: es gibt compiler, die ein "passendes" Verhalten für volatile garantieren, also "acquire" fürs Lesen und "release" fürs Schreiben. MSVC 8 z.B. tut das. Im C++0x Standard ist es IIRC auch vorgesehen. Der aktuelle Java Standard schreibt es AFAIK auch vor. Es gibt also ein paar wenige Situationen wo volatile hier ausreichend ist. Ganz allgemein zu behaupten volatile wäre hier ausreichend ist aber falsch.
-
Gut!
Dann könnte man aber immer noch InterlockedExchange verwenden (oder den Prozessor/OS spezifischen Befehl) und man ist aus dem Schneider ohne Synchronisation (Mutex/Critical Section etc.).PS: Gilt meines Wissens aber auch für x64...
-
InterlockedExchange "enthält" eine full memory barrier, ist also ausreichend zum schreiben.
Zum Lesen müsste man dann InterlockedCompareExchange (oder InterlockedCompareExchange_acq) verwenden.
Doof ist nur, dass es eben für x86 ein vollkommen unnötiger Overhead ist.
Im neuen C++ Standard wird es spezielle Funktionen hierfür geben, also Funktionen mit denen man explizit ein "load_acquire" bzw. "store_release" machen kann. Diese Funktionen könnte man dann auf x86 durch ein einfaches "mov" implementieren. Dann hätte man plattformübergreifend korrekten Code, der trotzdem auf x86 nicht unnötig langsam ist.
PS: Gilt meines Wissens aber auch für x64...
Jo, x86 und x64 sind dahingehend gleich. IA64 ist total anders. Aber auch ziemlich uninteressant weil ziemlich tot
