#include <iostream>
#include <thread>
#include <syncstream>
#include <vector>
#include <future>
int func(int id, std::stop_token token)
{
int ret = -1;
for (int ii = 0; ii < 50; ii++)
{
if (token.stop_requested())
{
return ret; //返回线程取消时的ret
}
ret = ii;
std::osyncstream(std::cout) << "[id]=" << id << ",ret=" << ret << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
return ret; //正常执行完时返回值
}
int main(int argc, char** argv)
{
std::stop_source sts;
std::vector<std::jthread> ths; //工作线程
std::vector<std::future<int>> tasks; //工作线程执行结果
for (int thid = 0; thid < 10; thid++)
{
std::packaged_task<int(int, std::stop_token)> task(func);
auto ft = task.get_future();
tasks.push_back(std::move(ft));
ths.emplace_back(std::move(task), thid, sts.get_token());
}
// 注册回调
// stop_source::request_stop()被调用时,线程被取消,callback触发调用
// 捕获列表需引用捕获,因jthread和future不可拷贝
std::stop_callback callback(sts.get_token(), [&ths, &tasks] {
for (int thid = 0; thid < 10; thid++)
{
if (tasks.at(thid).wait_for(std::chrono::milliseconds(1000)) == std::future_status::ready)
{
auto& fttmp = tasks.at(thid); //std::future不可拷贝,只能使用引用或指针
auto& thtmp = ths.at(thid); //std::thread不可拷贝
std::cout << "[id]=" << thid <<",[tid] = " << thtmp.get_id() << ",has canceled..,ret = " << fttmp.get() << std::endl;
}
}
});
//方法1:指定时间内存在线程没执行完,取消所有线程
int durationSec = 30;//指定全局的超时时间(s)
std::vector<std::future<std::future_status>> fss;//所有工作线程在durationSec时间段后的执行状态
std::atomic_bool allFinish(true); //是否所有线程均执行完毕
//因wait_for()会阻塞,为了同时判断各个工作线程是否执行完毕,创建和工作线程相同个数的【状态判断线程】,并行判定工作线程执行状态
for (int thid = 0; thid < 10; thid++)
{
std::future<std::future_status> fs = std::async(std::launch::async, [&tasks,thid, durationSec]() {
return tasks.at(thid).wait_for(std::chrono::seconds(durationSec));
});
fss.push_back(std::move(fs));
}
for (int thid = 0; thid < 10; thid++)
{
if (fss.at(thid).get() != std::future_status::ready)
{
allFinish.store(false);
}
}
if (allFinish.load()) //所有线程在duration内均执行完毕
{
for (int thid = 0; thid < 10; thid++)
{
std::cout << "[id]=" << thid << ",[tid]= " << std::this_thread::get_id() << "is goint to finish.." << ",ret=" << tasks.at(thid).get() << std::endl;
}
}
else //存在线程在duration内均执行完毕
{
std::cout << "not all threads finish in " << durationSec << "s," << "all threads are going to cancel.." << std::endl;
sts.request_stop();
}
////方法2:用户手动输入取消所有线程
//int flag = -1;
//std::cin >> flag;
//if (flag == 0)
//{
// std::cout << "all threads are going to cancel.." << std::endl;
// sts.request_stop();
//}
return 0;
}