说我们有一个简单的异步调用,我们想在超时时终止/终止/消除
// future::wait_for
#include <iostream> // std::cout
#include <future> // std::async, std::future
#include <chrono> // std::chrono::milliseconds
// a non-optimized way of checking for prime numbers:
bool is_prime (int x) {
for (int i=2; i<x; ++i) if (x%i==0) return false;
return true;
}
int main ()
{
// call function asynchronously:
std::future<bool> fut = std::async (is_prime,700020007);
// do something while waiting for function to set future:
std::cout << "checking, please wait";
std::chrono::milliseconds span (100);
while (fut.wait_for(span)==std::future_status::timeout)
std::cout << '.';
bool x = fut.get();
std::cout << "\n700020007 " << (x?"is":"is not") << " prime.\n";
return 0;
}
我们想在第一次超时发生后立即将其杀死。无法在将来找到一种方法。
我能找到的最接近停止正在运行的任务的方法是std::packaged_task
reset
方法,但它没有说明它是否可以中断正在运行的任务。那么如何使用boost线程或其他非stl库来杀死运行asyncrinusly的任务呢?
答案 0 :(得分:0)
我认为不可能安全地从循环本身外部中断运行周期,因此STL不提供这样的功能。当然,人们可能会试图杀死正在运行的线程,但它可能导致资源泄漏并不安全。
您可以检查is_prime
函数内的超时,并在超时发生时从中返回。或者,您可以尝试将对std::atomic<bool>
的引用传递给is_prime
,并在每次迭代时检查其值。然后,当超时发生时,您更改main
中的原子值,以便is_prime
返回。
答案 1 :(得分:0)
无法停止std::async
开箱即用...但是,您可以执行此操作,传递bool
以终止is_prime
方法并抛出如果超时则出现异常:
// future::wait_for
#include <iostream> // std::cout
#include <future> // std::async, std::future
#include <chrono> // std::chrono::milliseconds
// a non-optimized way of checking for prime numbers:
bool is_prime(int x, std::atomic_bool & run) {
for (int i = 2; i < x && run; ++i)
{
if (x%i == 0) return false;
}
if (!run)
{
throw std::runtime_error("timeout");
}
return true;
}
int main()
{
// call function asynchronously:
std::atomic_bool run;
run = true;
std::future<bool> fut = std::async(is_prime, 700020007, std::ref(run));
// do something while waiting for function to set future:
std::cout << "checking, please wait";
std::chrono::milliseconds span(100);
while (fut.wait_for(span) == std::future_status::timeout)
{
std::cout << '.';
run = false;
}
try
{
bool x = fut.get();
std::cout << "\n700020007 " << (x ? "is" : "is not") << " prime.\n";
}
catch (const std::runtime_error & ex)
{
// Handle timeout here
}
return 0;
}
在任意点停止线程是危险的,并且会导致资源泄漏,资源是指针,文件和文件夹的句柄,以及程序应该做的其他事情。
当杀死一个线程时,该线程可能会也可能不会正常工作。无论它做什么,它都无法完成,任何成功创建的变量都不会调用它们的析构函数,因为没有线程可以运行它们。