Как проверить, закончил ли поток работу в C ++ 11 и выше?

Как я могу проверить, закончил ли поток работу в 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
}
}

4

Решение

Вы можете использовать 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,

4

Другие решения

Ты хочешь будущего. Начните свою тему сstd::async и использовать wait_for с нулевыми секундами на нем. Сравните результат с future_status::ready,

1

Ты можешь использовать 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...
1

У меня была та же проблема, и мое решение заключалось в том, чтобы обернуть класс потока, чтобы я мог установить флаг, когда функция закончила свою работу.

Здесь вы найдете обсуждение решения Переполнение стека

И вот рабочий пример: Celma управляемая нить

0
По вопросам рекламы [email protected]