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).
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).
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.
Ale z jednym atomowym 'int' i wywołaniem systemowym jak' futex' na Linuksie, możesz zaimplementować prawidłowy muteks. –
@MikeSeymour Nie bardzo. –
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. –
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.
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.
"Muteks może być zaimplementowany za pomocą prostego' std :: atomic '" nie oznacza, że jest to optymalna implementacja. –
'atomowy' to "muteks" biedaka "... to znaczy, ** naprawdę ** biedaka. –
Griwes
Zastanawiam się, dlaczego niektórzy uważają, że to pytanie jest niejasne lub nieprzydatne. –