Я хотел бы проверить, завершилось ли выполнение std::thread
. При поиске в stackoverflow я нашел следующий вопрос, который касается этого проблема. В принятом ответе предлагается, чтобы рабочий поток устанавливал переменную прямо перед выходом, а основной поток проверял эту переменную. Вот минимальный рабочий пример такого решения:
#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
из кеша своего процессора. Когда рабочий процесс обновляет его, протокол когерентности кеша заботится о записи изменений рабочих процессов в глобальную память и аннулировании кеша ЦП основного потока, поэтому он должен считывать обновленное значение из глобальной памяти. Разве весь смысл когерентности кеша не в том, чтобы код, подобный приведенному выше, просто работал?