C hat einen neuen Standard erhalten, seit diese Frage gestellt wurde (und zuletzt beantwortet).
C11 kommt jetzt mit Multithreading-Unterstützung und behandelt das Multithreading-Verhalten von Streams:
§7.21.2 Streams
¶7 Jeder Stream hat ein zugehöriges Schloss, das verwendet wird, um Datenkonflikte zu verhindern, wenn mehrere Ausführungsstränge auf einen Stream zugreifen, und um die Verzweigung von Streamoperationen, die von mehreren Threads ausgeführt werden, zu beschränken. Nur ein Thread kann dieses Schloss gleichzeitig halten. Das Schloss ist reentrant: Ein einzelner Thread kann das Schloss mehrmals zu einem bestimmten Zeitpunkt halten.
¶8 Alle Funktionen, die einen Stream lesen, schreiben, positionieren oder die Position eines Streams abfragen, sperren den Stream, bevor sie darauf zugreifen. Sie geben das mit dem Stream verknüpfte Schloss frei, wenn der Zugriff abgeschlossen ist.
Also muss eine Implementierung mit C11-Threads garantieren, dass die Verwendung von printf
threadsicher ist.
Ob die Atomarität (wie bei keinem Verzweigen) garantiert ist, war mir auf den ersten Blick nicht klar, weil der Standard von der Beschränkung des Verzweigens sprach, im Gegensatz zur Verhinderung, was er für Datenkonflikte vorschrieb.
Ich tendiere dazu zu glauben, dass es garantiert ist. Der Standard spricht von der Beschränkung des Verzweigens, da bestimmte Verzweigungen, die das Ergebnis nicht ändern, immer noch erlaubt sind; z.B. fwrite
einige Bytes, fseek
zurück und fwrite
bis zur ursprünglichen Position, sodass beide fwrite
s hintereinander liegen. Die Implementierung kann diese 2 fwrite
s neu anordnen und sie zu einem einzelnen Schreibvorgang zusammenführen.
1: Siehe den durchgestrichenen Text in der Antwort von R.. für ein Beispiel.