Я хотел бы проверить, завершено ли выполнение std::thread
. Поиск stackoverflow я нашел следующий question, который решает эту проблему. В принятом ответе предлагается, чтобы рабочий поток установил переменную прямо перед выходом и основной поток проверил эту переменную. Вот минимальный рабочий пример такого решения:
#include <unistd.h>
#include <thread>
void work( bool* signal_finished ) {
sleep( 5 );
*signal_finished = true;
}
int main()
{
bool thread_finished = false;
std::thread worker(work, &thread_finished);
while ( !thread_finished ) {
// do some own work until the thread has finished ...
}
worker.join();
}
Кто-то, кто прокомментировал принятый ответ, утверждает, что в качестве сигнала нельзя использовать простую переменную bool
, код был сломан без барьера памяти и использование std::atomic<bool>
было бы правильным. Моя первоначальная догадка заключается в том, что это неправильно, и простого bool
достаточно, но я хочу убедиться, что я чего-то не упускаю. Требуется ли для вышеуказанного кода std::atomic<bool>
правильно?
Предположим, что основной поток и рабочий выполняются на разных ЦП в разных сокетах. Я думаю, что произойдет, что основной поток читает thread_finished
из своего кэша процессора. Когда работник обновляет его, протокол когерентности кэша берет на себя обязательство написать рабочие изменения в глобальную память и аннулировать кеш процессора основного потока, чтобы он считывал обновленное значение из глобальной памяти. Разве не все указывает на то, что когерентность кеша делает код, подобный приведенному выше, просто работает?