如何在c中实现函数超时

新手上路,请多包涵

我有函数 f;我想在启动 f 后抛出异常 1s。我无法修改 f()。有可能用c ++做到吗?

 try {
   f();
}
catch (TimeoutException& e) {
//timeout
}

原文由 Newbie 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 831
2 个回答

您可以创建一个单独的线程来运行调用本身,并在主线程中等待一个条件变量,一旦它返回,将由调用 f 的线程发出信号。诀窍是在 1s 超时的情况下等待条件变量,这样如果调用花费的时间比超时时间长,你仍然会醒来,知道它,并能够抛出异常——所有这些都在主线程中。这是代码( 这里 是现场演示):

 #include <iostream>
#include <chrono>
#include <thread>
#include <mutex>
#include <condition_variable>

using namespace std::chrono_literals;

int f()
{
    std::this_thread::sleep_for(10s); //change value here to less than 1 second to see Success
    return 1;
}

int f_wrapper()
{
    std::mutex m;
    std::condition_variable cv;
    int retValue;

    std::thread t([&cv, &retValue]()
    {
        retValue = f();
        cv.notify_one();
    });

    t.detach();

    {
        std::unique_lock<std::mutex> l(m);
        if(cv.wait_for(l, 1s) == std::cv_status::timeout)
            throw std::runtime_error("Timeout");
    }

    return retValue;
}

int main()
{
    bool timedout = false;
    try {
        f_wrapper();
    }
    catch(std::runtime_error& e) {
        std::cout << e.what() << std::endl;
        timedout = true;
    }

    if(!timedout)
        std::cout << "Success" << std::endl;

    return 0;
}

原文由 Smeeheey 发布,翻译遵循 CC BY-SA 4.0 许可协议

可以新建一个线程,异步等待1s过去,然后抛出异常。但是,异常只能在抛出它们的同一线程中捕获,因此,您不能在调用 f() 的同一线程中捕获,就像在您的示例代码中一样 - 但这不是规定的要求,所以对你来说可能没问题。

只有当 f 保证在 1s 内返回时,你才能同步执行此操作:

  • 存储当前时间
  • 致电 f()
  • 等待当前时间 - 存储时间 + 1s

但可能很难证明 f 实际上确实及时返回。

原文由 eerorika 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题