Я изучаю С++ 11 concurrency, где мой единственный предыдущий опыт с примитивами concurrency был в классе Operating Systems шесть лет назад, поэтому будьте осторожны, если сможете.
В С++ 11 мы можем написать
std::mutex m;
std::condition_variable cv;
std::queue<int> q;
void producer_thread() {
std::unique_lock<std::mutex> lock(m);
q.push(42);
cv.notify_one();
}
void consumer_thread() {
std::unique_lock<std::mutex> 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 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
до YUM
. Кроме того, если notify()
требует, чтобы вы передали блокировку, это хороший способ убедиться, что люди фактически блокируют мьютекс перед вызовом notify()
(см. Сигнализация переменной условия (pthreads)).
Я уверен, что С++ 11 не имеет стандартной реализации этой идиомы. Какая историческая причина для этого (разве это просто так, что pthreads этого не делали, и почему это так)? Есть ли техническая причина, по которой авантюрный С++-кодер не смог реализовать эту идиому в стандартном С++ 11, назвав ее, возможно, my_better_condition_variable
?
У меня также есть смутное чувство, что, возможно, я изобретаю семафоры, но я недостаточно помню из школы, чтобы узнать, насколько это точно или нет.