如何在超时时停止异步求值函数

How to stop a async evaluating function on timeout?

本文关键字:异步 函数 超时      更新时间:2023-10-16

说我们有一个简单的异步调用,我们想在超时时终止/消除

// 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库的情况下杀死异步运行的任务呢?

无法立即停止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;
}

为什么能够停止线程是糟糕的

在任意点停止线程是危险的,会导致资源泄漏,其中资源是指针、文件和文件夹的句柄,以及程序应该做的其他事情

杀死线程时,线程可能正在工作,也可能不在工作。无论它在做什么,它都不会完成,任何成功创建的变量都不会调用它们的析构函数,因为没有线程可以运行它们

我在这里概述了一些问题。

我认为不可能从循环本身之外安全地中断正在运行的循环,所以STL不提供这样的功能。当然,可以尝试杀死正在运行的线程,但这并不安全,因为可能会导致资源泄漏。

您可以在is_prime函数中检查超时,如果发生超时,则从中返回。或者,您可以尝试将对std::atomic<bool>的引用传递给is_prime,并在每次迭代中检查其值。然后,当超时发生时,更改main中原子的值,使is_prime返回。