【问题标题】:Setting timeout for c/c++ function call为 c/c++ 函数调用设置超时
【发布时间】:2018-11-14 10:23:37
【问题描述】:

假设我的主函数调用了一个外部函数veryslow()

int main(){... veryslow();..}

现在我想在 main 中调用very_slow 的部分,这样如果超过时间限制,veryslow 就会终止。像这样的

int main(){... call_with_timeout(veryslow, 0.1);...}

实现这一目标的简单方法是什么?我的操作系统是 Ubuntu 16.04。

【问题讨论】:

  • 修改 veryslow() 以将持续时间作为参数,然后在必要时退出。

标签: c++ timeout


【解决方案1】:

你可以在一个新线程中调用这个函数,并设置一个超时时间来终止线程,它会结束这个函数调用。

一个 POSIX 示例是:

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>

pthread_t tid;

// Your very slow function, it will finish running after 5 seconds, and print Exit message.
// But if we terminate the thread in 3 seconds, Exit message will not print.
void * veryslow(void *arg)
{
    fprintf(stdout, "Enter veryslow...\n");
    sleep(5);
    fprintf(stdout, "Exit veryslow...\n");

    return nullptr;
}

void alarm_handler(int a)
{
    fprintf(stdout, "Enter alarm_handler...\n");
    pthread_cancel(tid);    // terminate thread
}

int main()
{
    pthread_create(&tid, nullptr, veryslow, nullptr);

    signal(SIGALRM, alarm_handler);
    alarm(3);   // Run alarm_handler after 3 seconds, and terminate thread in it

    pthread_join(tid, nullptr); // Wait for thread finish

    return 0;
}

【讨论】:

  • 一个想法,一个很好的想法,但需要更多细节才能成为有用的答案。
  • 是的,我没有给出实际的代码示例,因为 OP 没有指定他正在使用的操作系统。线程相关的 API 在不同的操作系统中有所不同。
【解决方案2】:

我会将指向接口的指针传递给函数并要求返回。有了这个,我将启用两种通信方式来执行所有必要的任务——包括超时和超时通知。

【讨论】:

    【解决方案3】:

    您可以使用 future 超时。

    std::future<int> future = std::async(std::launch::async, [](){ 
        veryslow();
    });
    
    std::future_status status;
    
    status = future.wait_for(std::chrono::milliseconds(100));
    
    if (status == std::future_status::timeout) {
        // verySlow() is not complete.
    } else if (status == std::future_status::ready) {
        // verySlow() is complete.
        // Get result from future (if there's a need)
        auto ret = future.get();
    }
    

    请注意,没有内置方法可以取消异步任务。您必须在 verySlow 本身内部实现它。

    查看这里了解更多信息:

    http://en.cppreference.com/w/cpp/thread/future/wait_for

    【讨论】:

    • “没有内置方法可以取消异步任务” 那么在这种情况下使用future 有什么好处呢?这只会让事情变得更复杂。
    • @SidS:好吧,您可以继续并忽略调用。并且调用线程不会阻塞。基本上,您可以获得异步编程的所有好处。
    • 但它仍在运行。问题是如何让它在一段时间后停止运行。
    • @SidS:最好的办法是修改verySlow 本身。杀死一个线程从来都不是一个好主意,但是如果你坚持,在一个线程中运行verySlow,等待调用线程超时,如果它还在运行,然后杀死线程。
    • 我同意,最好的办法是修改veryslow()。在这种情况下不需要多线程。
    猜你喜欢
    • 2011-12-06
    • 2019-03-27
    • 1970-01-01
    • 1970-01-01
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-14
    相关资源
    最近更新 更多