2013-05-22 12 views
6

zamiast sizeof(std::atomic<bool>)==1?Dlaczego sizeof (std :: mutex) == 40 (gcc, clang, icc)?

Muteks może zostać zaimplementowany za pomocą prostego std::atomic<bool>, więc sądzę, że rozmiar muteksu może być tak mały jak ten, a może 4 (32bity).

+0

"Muteks może być zaimplementowany za pomocą prostego' std :: atomic '" nie oznacza, że ​​jest to optymalna implementacja. –

+2

'atomowy ' to "muteks" biedaka "... to znaczy, ** naprawdę ** biedaka. – Griwes

+3

Zastanawiam się, dlaczego niektórzy uważają, że to pytanie jest niejasne lub nieprzydatne. –

Odpowiedz

11

Z jednym bool można zaimplementować tylko blokadę spin-lock. Zauważ, że byłaby to nieuczciwa blokada, ponieważ nic nie gwarantuje, że kelnerzy ustawiają się w kolejce, więc istnieje szansa, że ​​pod wysokim rywalem w najbardziej ekstremalnym przypadku wątek mógł zostać zablokowany na zawsze, ponieważ zawsze straciłby wyścig, by zdobyć zamek.

Implementacja mutex wymaga wsparcia z systemu operacyjnego, aby móc uśpić oczekujące wątki. Tak więc muteks potrzebowałby flagi informującej, czy jest ona zablokowana, oraz pewnej postaci deskryptora kolejki, która pozwala na uśpienie oczekujących wątków i ich obudzenie. Jeśli chcesz, aby muteks był w stanie obsługiwać blokowanie rekursywne, odporność, opcjonalne wirowanie, ochronę przed inwersją priorytetową itd., Potrzebowałby jeszcze więcej członków.

+0

Ale z jednym atomowym 'int' i wywołaniem systemowym jak' futex' na Linuksie, możesz zaimplementować prawidłowy muteks. –

+0

@MikeSeymour Nie bardzo. –

+0

Masz na myśli "Nie, nie możesz" lub "Naprawdę, skoro używasz pamięci jądra, a także przestrzeni użytkownika' int "? Będę się nie zgadzał, jeśli masz na myśli pierwszy. –

11

Biblioteka GNU zwykle używa wątków Posix do implementacji standardowej biblioteki wątków. To wykorzystuje jeden typ pthread_mutex_t do reprezentowania kilku różnych typów muteksów; więc zawiera różne pola potrzebne dla bardziej złożonych muteksów (np. licznik dla rekurencyjnych muteksów) plus pole do określenia typu.

Masz rację, że w zasadzie przy odpowiedniej obsłudze systemu operacyjnego, std::mutex może zużywać zaledwie jeden bajt pamięci użytkownika. (W systemie Linux musi to być int, a na innych platformach może to być uchwyt o rozmiarze całkowitym lub wielkości wskaźnika do zasobu jądra). Można przypuszczać, że zalety korzystania z dobrze przetestowanej istniejącej implementacji były większe niż korzyści zaoszczędzenia kilkudziesięciu bajtów na muteks.

6

Mutex może być realizowane za pomocą prostego std::atomic<bool>

To nie wygląda możliwości, biorąc pod uwagę, że mutex::lock jest wymagana operacja, a std::atomic<bool> jest najprawdopodobniej bez blokowania rodzaju. Można umieścić pętlę while wokół wywołania compare_exchange_strong, ale to nie jest to samo, co mutex::lock, ponieważ powoduje marnowanie procesora przez cały okres oczekiwania.

Ogólnie std::mutex jest dużo bardziej złożona, niż prosta bool z zachowaniem określonej wielowątkowym, wyjaśniający jego raczej większy rozmiar, który zależy od kompilatora, na przykład on ideone the sizeof(mutex) is 24.

Powiązane problemy