Hyper-Threading: Optimierungen und Fallen

Vorsicht: Selbst Integer ist nicht threadsafe

In vielen Situationen ist es nötig, dass Threads auf gemeinsame globale Variablen zugreifen. Solange dies nur lesend geschieht, ist das kein Problem. Kritischer wird es jedoch, wenn die Threads die Variablen auch verändern.

Verständlich sind die Probleme bei zusammengesetzten Variablen wie Arrays, Records, Strukturen oder Objekten. Ändert etwa ein Thread einen String, so geschieht dies Charakter für Charakter. Während dieses Updates kann er jedoch vom Scheduler mitten in der Arbeit unterbrochen werden. Zu diesem Zeitpunkt enthält ein Teil des Strings bereits den neuen Wert, der andere noch die alten Zeichen. Fällt die nächste Zeitscheibe an einen Thread, der ebenfalls auf den String zugreift, so arbeitet der neue Thread mit einem Zwischenstadium aus altem und neuem Wert. Was bei einem String eventuell noch ohne schlimme Folgen abläuft, führt spätestens bei über Pointer verketteten Listen ins Nirwana.

Deshalb ist es bei schreibendem Zugriff auf gemeinsame globale Variablen Pflicht, jeden Zugriff - auch den lesenden - durch Kernel-Funktionen abzusichern.

Was für komplexe Variablen klar ist, muss jedoch nicht unbedingt für einfache Variablen gelten. So sind viele Programmierer der Meinung, einen Zugriff auf einen gemeinsamen Integer-Wert nicht absichern zu müssen. Und sie haben sogar manchmal Recht, allerdings nur bei einer Single-CPU. In einer Hyper-Threading-Umgebung wird diese Annahme zur Falle.