volatile und boost condition variable
-
Hiho,
zum Abstimmen von 2 Threads benutzte ich boost und die condition variable nach folgendem Prinzip: http://www.boost.org/doc/libs/1_49_0/doc/html/thread/synchronization.html#thread.synchronization.condvar_ref
In der Doku wird die "bool data_read" als Flag genutzt. Nun ist diese im Beispiel nicht als volatile gekennzeichnet. Ist das an dieser Stelle wirklich nicht notwendig, oder sollte man es doch lieber setzen?VG
Pellaeon
-
Wieso willst du volatile überhaupt einsetzen? volatile garantiert in C++ keine Threadingsicherheit.
Die Variable data_ready ist im Beispiel durch ein Mutex-Objekt geschützt, welches gelockt wird:
boost::condition_variable cond; boost::mutex mut; bool data_ready; void process_data(); void wait_for_data_to_process() { boost::unique_lock<boost::mutex> lock(mut); // <- hier erfolgt der lock while(!data_ready) // somit ist in diesem Block // immer nur ein Thread gleichzeitig unterwegs. { cond.wait(lock); } process_data(); }
Grüssli
-
Ohne volatile darf der Compiler doch aggressiv optimieren und könnte die bool in ein Register schieben und da abfragen. Setzt Thread 1 nun die bool (im Hauptspeicher) auf true und ruft dann notify, Thread 2 pollt aber durch die Optimierung auf dem Register, kommt das nie an. volatile soll ja so etwas verhindern. Zumindest ist das mein Kenntnisstand dazu. Daher die Frage
-
volatile
kann sowas nicht unbedingt verhindern. Auch die CPU darf solche Optimierungen von sich aus durchführen.volatile
hat in C und C++ nichts mit Threading zu tun (im Gegensatz zu Java und C#). Das einzige wozuvolatile
dient, ist der CPU mitzuteilen, dass sich die Variable womöglich von extern verändern könnte. Zum Beispiel sind da PINs zu nennen bei einem Mikrokontroller.Dass hier der Speicher korrekt angefasst wird, dass garantiert eine Speicherbarriere (oder besser Memory Barrier). Diese werden von der Threadingbibliothek implementiert, bzw. schlussendlich vom Betriebsystem. Diese sind im Beispiel beim
lock
undwait
anzutreffen.http://en.wikipedia.org/wiki/Memory_barrier
Grüssli
-
Dein Kenntnisstand ist unzureichend
Sinnvollerweise gibt es Wege um dem Compiler mitzuteilen dass er solche Optimierungen nicht über einen bestimmten Punkt hinweg machen darf.
Die Dinger nennt man u.A. "Barriers" bzw. "Fences".Das Locken/Unlocken einer Mutex ist so eine Barrier (lock: Acquire-Barrier, unlock: Release-Barrier - bzw. auch manchen Systemen sind auch beide eine Full-Barrier).
Daher ist volatile hier nicht notwendig.
EDIT: hihi, zu spät
-
OK, danke für die Infos!!
VG
Pellaeon