2013-05-22 4 views
6

anstatt sizeof(std::atomic<bool>)==1?Warum ist sizeof (std :: mutex) == 40 (gcc, clang, icc)?

Ein Mutex könnte über eine einfache std::atomic<bool> implementiert werden, so würde ich denken, dass die Größe eines Mutex so klein sein könnte, oder vielleicht 4 (32Bits).

+0

"Ein Mutex könnte über eine einfache' std :: atomic 'implementiert werden" bedeutet nicht, dass es die optimale Implementierung ist. –

+2

'atomare ' ist ein 'mutex' des armen Mannes ... ich bedeute, ** wirklich ** der des armen Mannes. – Griwes

+3

Ich frage mich, warum manche diese Frage für unklar oder nicht nützlich halten. –

Antwort

11

Mit einem bool konnten Sie nur eine Spin-Lock implementieren. Beachten Sie, dass es eine unfaire Sperre wäre, da nichts dafür sorgt, dass sich die Kellner anstellen. Daher besteht die Möglichkeit, dass im Extremfall ein Thread für immer blockiert wird, weil er immer das Rennen verliert, um die Sperre zu erhalten.

Eine Mutex-Implementierung benötigt Unterstützung vom Betriebssystem, um die wartenden Threads in den Ruhezustand versetzen zu können. Ein Mutex benötigt also ein Flag, das angibt, ob es gesperrt ist, und eine Form eines Warteschlangendeskriptors, der es ermöglicht, wartende Threads in den Ruhezustand zu versetzen und sie zu wecken. Wenn der Mutex in der Lage sein soll, rekursives Sperren, Robustheit, optionales Drehen, Prioritätsinversionsschutz usw. zu unterstützen, würde er noch mehr Mitglieder benötigen.

+0

Aber mit einem atomaren 'int' und einem Systemaufruf wie' futex' unter Linux können Sie einen passenden Mutex implementieren. –

+0

@MikeSeymour Nicht wirklich. –

+0

Meinst du "Nein, du kannst nicht" oder "Nicht wirklich, da du etwas Kernel-Speicher sowie den User-Space' int' "verwendest? Ich muss widersprechen, wenn du das erste meinst. –

11

Die GNU-Bibliothek verwendet normalerweise Posix-Threads, um die Standard-Thread-Bibliothek zu implementieren. Das verwendet einen einzelnen Typ pthread_mutex_t, um mehrere verschiedene Arten von Mutex darzustellen; Daher enthält es verschiedene Felder, die für komplexere Mutexe benötigt werden (z. B. ein Zähler für rekursive Mutexe), sowie ein Feld zum Spezifizieren des Typs.

Sie haben recht, dass eine geeignete std::mutex mit geeigneter Unterstützung vom Betriebssystem so wenig wie ein Byte des Benutzerspeichers verwenden kann. (Unter Linux muss es sich um eine int handeln; auf anderen Plattformen könnte es sich um eine Ganzzahl oder ein Zeiger in der Größe eines Zeigers für eine Kernel-Ressource handeln). Vermutlich überwiegen die Vorteile der Verwendung einer gut getesteten vorhandenen Implementierung die Vorteile des Speicherns von ein paar Dutzend Bytes pro Mutex.

6

Ein Mutex könnte über eine einfache std::atomic<bool>

schauen Sie nicht wie eine Möglichkeit umgesetzt werden, wenn man bedenkt, dass mutex::lock eine erforderliche Operation ist, und std::atomic<bool> ist höchstwahrscheinlich eine nicht sperrende Art. Sie könnten eine while Schleife um den compare_exchange_strong Anruf setzen, aber das ist nicht das gleiche wie mutex::lock, weil es die CPU während der gesamten Wartezeit verschwendet.

Im Allgemeinen ist std::mutex viel komplexer als ein einfaches bool mit definiertem Multithread-Verhalten, was seine ziemlich große Größe erklärt, die vom Compiler abhängt: zum Beispiel on ideone the sizeof(mutex) is 24.