Я изучаю параллелизм C++11, где мой единственный предыдущий опыт работы с примитивами параллелизма был на курсе операционных систем шесть лет назад, так что будьте осторожны, если вы можете.
В C++11 мы можем написать
std::mutex m;
std::condition_variable cv;
std::queue q;
void producer_thread() {
std::unique_lock lock(m);
q.push(42);
cv.notify_one();
}
void consumer_thread() {
std::unique_lock lock(m);
while (q.empty()) {
cv.wait(lock);
}
q.pop();
}
Это прекрасно работает, но меня раздражает необходимость оборачивать cv.wait
в цикл. Причина, по которой нам нужен цикл, мне ясна:
Consumer (inside wait()) Producer Vulture
release the lock
sleep until notified
acquire the lock
I MADE YOU A COOKIE
notify Consumer
release the lock
acquire the lock
NOM NOM NOM
release the lock
acquire the lock
return from wait()
HEY WHERE'S MY COOKIE I EATED IT
Теперь я считаю, что одна из замечательных особенностей unique_lock
заключается в том, что мы можем передавать его, верно? Так что было бы очень элегантно, если бы мы могли сделать это вместо этого:
Consumer (inside wait()) Producer
release the lock
sleep until notified
acquire the lock
I MADE YOU A COOKIE
notify and yield(passing the lock)
wake(receiving the lock)
return from wait()
YUM
release the lock
Теперь у потока Vulture нет возможности налететь, потому что мьютекс остается заблокированным на всем пути от I MADE YOU A COOKIE
до НЮМ
. Кроме того, если notify()
требует, чтобы вы передали блокировку, это хороший способ гарантировать, что люди действительно заблокируют мьютекс перед вызовом notify()
(см. Сигнализация состояния переменная (pthreads)).
Я почти уверен, что C++11 не имеет стандартной реализации этой идиомы.Какова историческая причина этого (просто pthreads этого не делал? и тогда почему это)? Есть ли техническая причина, по которой предприимчивый программист C++ не смог реализовать эту идиому в стандартном C++11, назвав ее, возможно, my_better_condition_variable
?
У меня также есть смутное ощущение, что, может быть, я заново изобретаю семафоры, но я недостаточно помню из школы, чтобы знать, верно это или нет.