Как я могу проверить, закончил ли поток работу в C ++ 11 и выше? Я читал документацию и написал следующий код:
#include <iostream>
#include <thread>
void mythread()
{
//do some stuff
}
int main()
{
std::thread foo(mythread);
if (foo.joinable())
{
foo.join();
//do some next stuff
}
}
joinable
говорит только, что поток начал работать, но я хотел бы знать, как написать код, чтобы проверить, завершил ли поток работу.
Например:
#include <iostream>
#include <thread>
void mythread()
{
//do some stuff
}
int main()
{
std::thread foo(mythread);
if (foo.finishedWork())
{
foo.join();
//do some next stuff
}
}
Вы можете использовать std::future
, он предоставляет средства более высокого уровня, где вы можете тривиально проверить, завершено ли асинхронное вычисление (или готово): Пример:
void mythread() {
//do some stuff
}
template<typename T>
bool future_is_ready(std::future<T>& t){
return t.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
}
int main()
{
std::future<void> foo = std::async(std::launch::async, mythread);
if (future_is_ready(foo)){
//do some next stuff
}
}
С другой стороны, вы можете подумать, что просто использование «безопасного» (или атомарного) флага работает:
#include <iostream>
#include <thread>
std::atomic<bool> is_done{false};
void mythread()
{
//do some stuff
......
is_done = true;
}
int main()
{
std::thread foo(mythread);
if (is_done)
{
foo.join();
//do some next stuff
}
.....
if(foo.joinable()) foo.join();
}
Но это не работает. Пока ты думаешь is_done = true
это последнее, что вы сделали в mythread()
; Возможно, вы создали несколько объектов продолжительность автоматического хранения в этой области, и так как такие объекты уничтожаются в обратном порядке построения, в этом потоке все еще будет «некоторая работа» после установки is_done
,
Ты хочешь будущего. Начните свою тему сstd::async
и использовать wait_for
с нулевыми секундами на нем. Сравните результат с future_status::ready
,
Ты можешь использовать wait_for
из std::future
проверить, есть ли результат уже там. Простой способ получить будущее для асинхронной задачи std::async
,
#include <future>
// ...
// launch task and get result future
auto rf = std::async(std::launch::async, mythread);
// get initial status
auto status = rf.wait_for(std::chrono::nanoseconds(1));
// loop while task is not ready
while(status != std::future_status::ready)
{
// not ready yet, do other stuff here
// 1 nanosecond timeout check
status = rf.wait_for(std::chrono::nanoseconds(1));
}
// we are done...
У меня была та же проблема, и мое решение заключалось в том, чтобы обернуть класс потока, чтобы я мог установить флаг, когда функция закончила свою работу.
Здесь вы найдете обсуждение решения Переполнение стека
И вот рабочий пример: Celma управляемая нить