Давайте сделаем этот бетон.Предложенная альтернатива условным переменным состоит в том, чтобы «официант» делал это:
loop:
lock mutex
check predicate
if (predicate is false)
unlock mutex
sleep a bit // (is this what you had in mind?)
goto loop
И «сигнализатор» делал это:
lock mutex
make predicate true
unlock mutex
Здесь «предикат» можетнапример, «очередь не пуста».
При таком подходе есть две проблемы.Первый - это тот, который вы определили: постоянный опрос неэффективен.Если вы представляете сотни или тысячи потоков во всей системе, пытающихся работать таким образом, это поставит систему на колени.Или ваш «сон немного» должен был быть настолько длинным, что сами по себе сон усугублял бы раздражающие задержки.
Вторая проблема более тонкая.Нет гарантии, что когда поток разблокирует мьютекс, а затем снова его блокирует, другому потоку, ожидающему этот мьютекс, будет разрешено работать.(Это свойство мьютекса называется "справедливостью"; мьютекс, обеспечивающий его, называется "справедливым". POSIX не требует, чтобы мьютексы были справедливыми.) Независимо от того, как долго вы спите в "waiter ", нет никакой гарантии, что" сигнализатор " когда-либо справится с вызовом lock mutex
.
Переменные условия решат обе эти проблемы.