Nie wierzę, że możesz zrobić coś takiego z boost :: thread. Być może dlatego, że zmienne warunkowe POSIX nie dopuszczają tego typu konstrukcji. Oczywiście, Windows ma WaitForMultipleObjects w formie opublikowanej, co może być rozwiązaniem, jeśli chcesz ograniczyć swój kod do prymitywów synchronizacji systemu Windows.
Inną opcją byłoby użycie mniejszej liczby zmiennych warunkowych: wystarczy mieć 1 zmienną warunku, którą uruchamiasz, gdy wydarzy się coś "interesującego". Następnie, za każdym razem, gdy chcesz czekać, uruchamiasz pętlę, która sprawdza, czy pojawiła się twoja szczególna sytuacja, a jeśli nie, wróć do oczekiwania na zmienną warunku. Trzeba czekać na tych zmiennych stanu, w takiej pętli tak czy inaczej, jako warunek zmiennych czeka podlegają fałszywych wybudzeń (od docs boost :: wątku, podkreślenie moje):
void wait(boost::unique_lock<boost::mutex>& lock)
...
efekty:
Atomowo zadzwoń pod numer lock.unlock()
i zablokuj bieżący wątek. Wątek zostanie odblokowany po otrzymaniu powiadomienia przez wywołanie this->notify_one()
lub this->notify_all()
lub podświadomie. ...
Wydaje mi się, że posiadanie trzeciej zmiennej warunkowej dla "1 lub 2 zmienionych" jest rzeczywiście najlepszym podejściem. Innym podejściem jest przekonwertowanie warunku oczekiwania na warunek na oczekiwanie deskryptorów plików za pomocą select i użycie potoków do komunikacji wątków. Ponieważ to pytanie jest ogólne (nie wyjaśnia, na co czeka się), nie jest jasne, czy wybór będzie lepszy. –
Problem z użyciem jednej zmiennej warunkowej to enkapsulacja. Nie możesz mieć żadnych funkcji, takich jak 'GoStyleChannel :: receive_but_break_if (condition_variable & cv, function & pred)'. Innymi słowy, załóżmy, że masz jakąś funkcję blokującą, która już używa zmiennej warunku. Chcesz go zablokować, dopóki nie stanie się warunek * lub * twój stan się stanie. Nie możesz tego zrobić bez posiadania globalnej 'std :: condition_variable somethingHasHappenedSomewhere', która jest naprawdę bzdura. – Timmmm