问题描述
一段时间以来,我一直在尝试使用 std::thread
,在我的项目中,我想确保线程不会一次做一件事,这就是我尝试制作一个简单项目的原因有类似“检查”线程是否完成的东西,然后重新开始
#include <future>
#include <thread>
#include <chrono>
#include <iostream>
using namespace std::chrono_literals;
void Thing()
{
std::this_thread::sleep_for(3s);
}
int main()
{
std::packaged_task<void()> task(Thing);
auto future = task.get_future();
std::thread t(std::move(task));
while (true) {
auto status = future.wait_for(0ms);
if (status != std::future_status::ready)
{
std::cout << "not yet" << std::endl;
}
else
{
t.join();
std::cout << "Join()" << std::endl;
}
std::this_thread::sleep_for(300ms);
}
}
使用此代码时,我在 std::cout << "Join()" << std::endl;
行出现错误,错误显示:Unhandled exception at 0x7632A842 in dasd.exe: Microsoft C++ exception: std::system_error at memory location 0x00AFF8D4.
当线程准备好并调用 t.join()
时会出现此错误。
这个项目的输出:
not yet
...
not yet
Join()
提前致谢
解决方法
如你所见https://en.cppreference.com/w/cpp/thread/thread/join
join
具有作为后置条件
joinable() 为假
并且处于错误状态
invalid_argument if joinable() 为 false
所以你不能两次调用它。
您可能希望在调用 join
或重写循环后中断循环,例如:
while (future.wait_for(300ms) != std::future_status::ready) {
std::cout << "not yet" << std::endl;
}
t.join();
std::cout << "Join()" << std::endl;
,
实际上,您不需要 while
循环。相反,您可以简单地调用 join
。
join
的作用是等待线程完成其工作。线程完成其工作后,它退出并清理堆栈,第二次调用 join
完全没有意义。
我还建议您使用 std::async
,以防您想要一个也返回值的异步函数。