Muszę po prostu mieć chwilę, bo to powinno być łatwe, ale nie mogę sprawić, żeby działało prawidłowo.Licznik atomów w gcc
Jaki jest poprawny sposób na wprowadzenie licznika atomowego w GCC?
tj. Chcę mieć licznik, który działa od zera do 4 i jest bezpieczny dla wątków.
robiłem to (co jest dodatkowo owinięte w klasie, ale nie tutaj)
static volatile int _count = 0;
const int limit = 4;
int get_count(){
// Create a local copy of diskid
int save_count = __sync_fetch_and_add(&_count, 1);
if (save_count >= limit){
__sync_fetch_and_and(&_count, 0); // Set it back to zero
}
return save_count;
}
Ale to działa od 1 do od 1 - 4 włącznie następnie wokół zera.
Powinno to trwać od 0 do 3. Normalnie chciałbym zrobić licznik z operatorem mod, ale nie wiedzieć, jak to zrobić bezpiecznie.
Być może ta wersja jest lepsza. Czy widzisz jakieś problemy z tym, lub oferują lepsze rozwiązanie.
int get_count(){
// Create a local copy of diskid
int save_count = _count;
if (save_count >= limit){
__sync_fetch_and_and(&_count, 0); // Set it back to zero
return 0;
}
return save_count;
}
Właściwie, powinienem zaznaczyć, że nie jest absolutnie krytyczne, że każda nić ma inną wartość. Jeśli dwa wątki odczytałyby tę samą wartość w tym samym czasie, to nie byłoby problemu. Ale w żadnym momencie nie mogą przekroczyć limitu.
To, czy __sync_fetch_and_add "wykonuje jedną operację atomową na inwokację", zależy od CPU - nieokreślonego w pytaniu. Można go również zaimplementować zgodnie z twoim podejściem do porównywania i zamieniania, które stosowałem wcześniej w sprzęcie firmy Sun (no cóż, moja była współpracownica była koleżanką o imieniu "atomic_robin" :-)). –
Nie mówiłem o liczbie wykonanych instrukcji; istnieją różne sposoby implementacji funkcji wymiany-dodawania, ale wszystkie są równoważne, o ile tylko zapisują dane w pamięci ("commit") raz. Chodzi o to, że nie można zbudować jednego "dużego" atomowego prymitywu z kilku małych; nie tworzą. Możesz użyć wielu kroków, ale krok końcowy (zatwierdzenie) musi być pojedynczą operacją atomową, która sprawia, że wszystko jest widoczne. Jeśli na końcu jest więcej takich kroków, automatycznie masz warunki wyścigu. –
Hej dzięki. Właśnie tego szukam. Nie wiem dokładnie, co myślałem z drugim rozwiązaniem. Domyślam się, że to brak snu spowodował, że napisałem tak dobry kod. – Matt