Код ниже демонстрирует мою ситуацию.
Код: Выделить всё
#include
#include
#include
void race_test() {
std::atomic data = 0;
std::atomic_bool flag = false;
constexpr std::size_t REP_COUNT = 1000;
std::thread inc_thread{[&] {
for (std::size_t i = 0; i != REP_COUNT; ++i) {
data.fetch_add(1, std::memory_order_relaxed);
flag.store(true, std::memory_order_release);
flag.notify_one();
}
}};
std::thread dec_thread{[&] {
for (std::size_t i = 0; i != REP_COUNT; ++i) {
while (data.load(std::memory_order_relaxed) == 0) {
flag.wait(false, std::memory_order_acquire);
flag.store(false, std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_seq_cst);
}
data.fetch_sub(1, std::memory_order_relaxed);
}
}};
inc_thread.join();
dec_thread.join();
}
int main()
{
for (std::size_t i = 0; i != 1000; ++i)
race_test();
}
Код: Выделить всё
dec_thread
This should repeat REP_COUNT times for each thread with data ending as 0.
In the "real world" a producer thread pushes to a thread-safe queue at it's leisure then Уведомляет потребительский поток для обработки всех доступных данных. Намеренно, что inc_thread потенциально может «забежать впереди» dec_thread . Цель состоит в том, что данные своевременно потребляются после производства. Я только что сделал данные атомного целого числа здесь, так как его было достаточным для демонстрации.
Это в настоящее время «работает», но гарантированно ли это будет работать? /> Я думаю, что это происходит потому, что dec_thread flag.store (false) происходит между inc_thread flag.store (true) и flag.notify_one () эффективно стирает следующее уведомление.
std :: atomic_thread_fence (std :: memory_order_seq_cst) предотвращает переупорядочение flag.store (false) и data.load () , и я могу видеть, как это предотвратит тупик, но тогда не так: место?
Я правильно понимаю ситуацию? Законный тупик или я полагаюсь на какое-то специфическое поведение x86?
Что нужно изменить, чтобы это действительно гарантировало работать? Пример с 1000 повторений, казалось, был достаточно для тупика около половины времени без забора.
Подробнее здесь: https://stackoverflow.com/questions/795 ... he-current