如何在超时时停止异步评估功能?
How to stop a async evaluating function on timeout?
假设我们有一个简单的异步调用,我们希望在超时时kill/terminate/eliminate
// 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 库的情况下 运行 asyncrinus 终止一项任务?
我认为从循环本身之外安全地中断 运行 循环是不可能的,所以 STL 不提供这样的功能。当然,可以尝试杀死 运行 线程,但这并不安全,可能会导致资源泄漏。
您可以在 is_prime
函数中检查超时,如果发生超时,则从中检查 return。或者您可以尝试将对 std::atomic<bool>
的引用传递给 is_prime
并在每次迭代时检查其值。然后,当超时发生时,您更改 main
中原子的值,因此 is_prime
returns.
无法立即停止 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("timed out!");
}
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;
}
为什么能够停止线程不好。
在任意点停止线程是危险的,会导致资源泄漏,其中资源是指针、文件和文件夹的句柄以及程序应该做的其他事情。
终止线程时,线程可能正在工作也可能不工作。无论它在做什么,它都不会完成,任何成功创建的变量都不会调用它们的析构函数,因为没有线程可以 运行 它们。
假设我们有一个简单的异步调用,我们希望在超时时kill/terminate/eliminate
// 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 库的情况下 运行 asyncrinus 终止一项任务?
我认为从循环本身之外安全地中断 运行 循环是不可能的,所以 STL 不提供这样的功能。当然,可以尝试杀死 运行 线程,但这并不安全,可能会导致资源泄漏。
您可以在 is_prime
函数中检查超时,如果发生超时,则从中检查 return。或者您可以尝试将对 std::atomic<bool>
的引用传递给 is_prime
并在每次迭代时检查其值。然后,当超时发生时,您更改 main
中原子的值,因此 is_prime
returns.
无法立即停止 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("timed out!");
}
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;
}
为什么能够停止线程不好。
在任意点停止线程是危险的,会导致资源泄漏,其中资源是指针、文件和文件夹的句柄以及程序应该做的其他事情。
终止线程时,线程可能正在工作也可能不工作。无论它在做什么,它都不会完成,任何成功创建的变量都不会调用它们的析构函数,因为没有线程可以 运行 它们。