【问题标题】:Control thread execution time in async异步控制线程执行时间
【发布时间】:2020-01-08 03:38:35
【问题描述】:

我有一个异步进程正在运行(使用std::async),我想测量执行时间并在执行时间过长时终止它。此过程在执行后还会返回一个值,如果计算时间过长,我想分配一些默认值作为结果。任何帮助/建议将不胜感激!

#include <thread>
#include <future>

int compute(int val)
{
    int result;

    // do large computations

    return result;
}
void main()
{
    auto compute_thread = std::async(compute, 100);

    // TODO: wait for result only for x milliseconds else assign some default value
    int result = compute_thread.get();

    // resume sequential code.
    int final = result * 2;
}

【问题讨论】:

  • 让异步任务监控它使用的时间,如果超过时间限制则清理并退出返回默认值。没有干净的方法可以杀死线程。
  • 如果你把等待逻辑放在compute() 函数中会怎样。执行快时返回一个值,否则返回另一个值(提前返回)。
  • @AlanBirtles 是否可以监视 main() 中的原子变量而不是线程本身?线程设置原子变量的状态。由于在线程级别高频检查原子状态会使架构复杂化。
  • 想要...杀死它 你不能杀死一个线程。对不起。如果你想让它终止,你必须让它想要终止。

标签: c++ multithreading c++11 asynchronous


【解决方案1】:

这是我的想法的样子(参见内联代码 cmets):

// Performs computations and exits when computation takes
// longer than maxTime. If the execution is timed out
// function returns valueIfTooLong.
// If the computation complete the function returns 0.
static int compute(int maxTime /*ms*/, int valueIfTooLong)
{
  auto start = std::chrono::steady_clock::now();
  for (short i = 0; i < std::numeric_limits<short>::max(); ++i)
  {
    auto now = std::chrono::steady_clock::now();
    if (std::chrono::duration_cast<std::chrono::milliseconds>(now - start).count() > maxTime)
    {
      return valueIfTooLong;
    }
  }

  return 0;
}

函数的使用:

int main()
{
  const auto valueIfTooLong = 111;
  const auto waitingTime = 10; // ms.
  auto compute_thread = std::async(std::launch::async, compute, waitingTime, valueIfTooLong);

  // Wait for result only for waitingTime milliseconds else assign valueIfTooLong
  int result = compute_thread.get();
  if (result == valueIfTooLong)
  {
    std::cout << "The calculation was longer than "
              << waitingTime << "ms. and has been terminated" << '\n';
  }
  else
  {
    std::cout << "The calculation is done" << '\n';
  }

  return 0;
}

【讨论】:

    【解决方案2】:

    你可以使用

    std::future<int> compute_thread;
    void main()
    {
        auto timeToWait = std::chrono::system_clock::now() + std::chrono::minutes(1); // wait for a minute
        compute_thread = std::async(compute, 100);
    
        // TODO: wait for result only for x milliseconds else assign some default value
        std::future_status status = compute_thread.wait_until(timeToWait);
    
        if(status == std::future_status::ready)
            int final = compute_thread.get() * 2;
        else
            // you need another value based on what you're doing
    }
    

    注意:如果你的 async 是一个很长的计算,你可能有另一个函数,例如计算相同的东西但不太准确...... 在这种情况下,同步任务不会被终止。您只需等待完成(如果及时),如果结果还没有准备好,您就继续工作......这是一种不被compute_thread.wait()阻止的方法

    注意 2:std::future&lt;int&gt; compute_thread 被声明为全局,因为如果您在函数中(而不是在主函数中)执行此操作,您必须确保 compute_thread 的生命周期比函数生命周期长。

    【讨论】:

    • 这不会阻止compute 运行,它使用全局状态。
    • @Caleth 它写在笔记中,阅读它们......这是一种不停等待结果的方法......我认为等待结果是问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-26
    相关资源
    最近更新 更多