close
требует заблокированного владения m
при настройке done
и notified
. И дело не в древней архитектуре, а в современной кэшированной архитектуре. Без заблокированного владения m
нет никакой гарантии, что обновленные значения done
и notified
сброшены за пределы строки кэша close
, так что они могут быть прочитаны consume
.
Является ли m
заблокированным во время cond_var.notify_one()
не так важно. И то, и другое верно, и я видел статьи, в которых утверждается, что один или другой являются наиболее производительными.
В целом, любой из них является правильным:
void close()
{
std::lock_guard lock{m};
done = true;
notified = true;
cond_var.notify_one();
}
или:
void close()
{
{
std::lock_guard lock{m};
done = true;
notified = true;
}
cond_var.notify_one();
}
Обратите внимание, я предполагаю C ++ 17 с отсутствием <std::mutex>
на lock_guard
. Я мог бы также использовать unique_lock
вместо lock_guard
здесь, но lock_guard
- самый простой инструмент для этой работы.