Der Futex (Kurzform für Fast Userspace Mutex) ist die zentrale Synchronisations-Primitive des Linux-Kernels. Er kombiniert die Schnelligkeit einer atomaren Userspace-Operation mit der Bequemlichkeit einer Kernel-Warteschlange: Im konfliktfreien Fall passiert kein einziger Syscall, erst wenn zwei Threads wirklich um dieselbe Sperre kämpfen, greift der Kernel ein.
Idee und Funktionsweise
Ein Futex ist ein 32-Bit-Zähler in einem von mehreren Threads geteilten Speicherbereich. Eine Sperre wie pthread_mutex testet diesen Zähler zunächst per atomarer Operation im Userspace:
- Glücklicher Pfad: Der Zähler ist frei, der Thread bekommt die Sperre sofort — ohne Betriebssystem-Aufruf. Das ist die Regel und macht den Futex extrem schnell.
- Konfliktfall: Ist die Sperre vergeben, ruft der Thread den Syscall
futex(2)auf:FUTEX_WAITlässt ihn im Kernel schlafen (in eine Warteschlange eintragen),FUTEX_WAKEweckt einen oder alle wartenden Threads wieder auf.
Der Kernel führt also die Warteschlange, in der blockierte Threads ruhen. Dadurch verbrennt ein wartender Thread keine CPU-Zeit — anders als beim Spinlock, der aktiv im Kreis schleift.
Warum so schnell?
Systemaufrufe kosten Zeit: Der Prozessor muss in den Kernel-Modus wechseln, der Overhead liegt je nach System im Bereich von Mikrosekunden. Ein Futex vermeidet diesen Wechsel in über 99 Prozent der Sperren-Operationen, weil der Zähler-Test und das Setzen der Sperre direkt im Userspace per Compare-and-Swap ablaufen. Erst wenn es wirklich eng wird, schaltet sich der Kernel ein. Auf diesen Bausteinen setzen praktisch alle glibc-Synchronisationsmechanismen auf: Mutex, Semaphor und Bedingungsvariablen — auch die Go-Runtime verwendet Futexe, wenn sie auf Linux läuft. Typische Producer-Consumer-Setups wie Work Queues oder Message Queues basieren ebenfalls auf diesen Bausteinen.
Wichtige Erweiterungen
- FUTEX_REQUEUE: Verschiebt wartende Threads in eine zweite Warteschlange — die Grundlage für effiziente Bedingungsvariablen in Monitoren.
- PI-Futexe (Priority Inheritance): Übertragen die Prioritätsvererbung in den Kernel und verhindern Prioritätsinversion — ein niedriger priorisierter Thread darf einen hoch priorisierten nicht dauerhaft blockieren. Wichtig für Echtzeit-Anwendungen, Basis der RT-Mutexe.
- Robuste Futexe: Beendet sich ein Prozess, der eine Sperre hält, crash-artig, kann der Kernel die Sperre automatisch freigeben und wartende Threads benachrichtigen — statt eines ewigen Hängens.
Abgrenzung zu anderen Primitive
- Gegenüber dem Spinlock: Der Spinlock dreht aktiv eine Schleife (verbraucht CPU, dafür extrem niedrige Latenz), der Futex schläft im Kernel (spart CPU, kostet aber einen Syscall und Kontextwechsel).
- Gegenüber einer reinen Userspace-Implementierung: Nur der Kernel kann Threads zuverlässig schlafen legen und wieder aufwecken; ein reiner Userspace-Ansatz müsste raten oder drehen.
- Der Futex ist ein Linux-Mechanismus — andere Betriebssysteme verwenden vergleichbare Bausteine (Windows: SRW-Locks und WaitOnAddress, macOS: Ulocks).
Verwandte Grundlagen: Mutex, Spinlock, atomare Operationen, Monitor, Lese-Schreib-Sperre, Kernel, Thread.