【问题标题】:How to limit the execution time of a function in C/POSIX?如何限制 C/POSIX 中函数的执行时间?
【发布时间】:2010-09-14 03:37:49
【问题描述】:

question 类似,我想在 C 中限制函数的执行时间——最好是微秒级精度。我想 C++ 异常可用于实现类似于this 的结果Python 解决方案。虽然并不理想,但这种方法在纯 C 语言中完全不可用。

那么,我想知道,在 Posix 系统上的 C 语言中,我如何在某个时间间隔之后中断函数的执行?对于相对简单的情况,silly business 工作得很好,但这会增加大量与问题解决方案正交的代码。假设我有一个这样的函数:

void boil(egg *e) { while (true) do_boil(e); }

我想在一个鸡蛋上运行煮沸*,每 50μs 中断一次以检查是否执行以下操作:

egg *e = init_egg(); while (true) { preempt_in(50, (void) (*boil), 1, e); /* Now boil(e) is executed for 50μs, then control flow is returned to the statement prior to the call to preempt_in. */ if (e->cooked_val > 100) break; }

我意识到可以使用 pthread 来执行此操作,但我更感兴趣的是避免使用它们。我可以在 SIGALRM 处理程序中在 ucontext_t 之间切换,但 POSIX 标准指出 setcontext/swapcontext 的使用不能在信号处理程序中使用,事实上,我注意到 Linux 和 Solaris 之间的不同行为这样做时的系统。

这种效果有可能达到吗?如果是这样,以便携的方式?

【问题讨论】:

    标签: c posix real-time portability preemption


    【解决方案1】:

    您可以使用线程,或者让函数轮询计时器(或由SIGALRM 处理程序设置的全局变量),然后保存其状态并在分配的时间到期时退出。 ucontext_t 的使用已被弃用,不应在新代码中使用,更不用说在信号处理程序中使用了。

    【讨论】:

    • 引用 ucontext_t 弃用?我认为相关的功能没有被广泛实施。
    • ucontext deprecated 的快速 google 查找有关特定供应商的信息,尤其是 Apple,将它们标记为已弃用。至于官方弃用,我没有立即引用,但我似乎记得 SUSv3 弃用了部分或全部功能,因为 C99 制作了一些指针转换构造,它需要未定义的行为。不过我得再看一遍才能确定……
    • 那么,我假设您的答案是否定的。根据您的估计,我将不得不进行投票或引入线程。
    【解决方案2】:

    请注意,您在此处寻找的一般功能称为成本执行。例如,请参阅WellingsLeung, et. al.'s great book 中的这篇文章。上面的答案集中在用户空间中实现它;一些 RTOS 或语言支持它(不是 linux)作为一般机制。

    提供此功能的一个示例操作系统是AUTOSAR OS (spec linked)。请注意,此操作系统提供执行时间强制,这与截止日期强制略有不同。执行时间强制越来越难,因为它依赖于某种能力来衡量实际花费的成本(通常与硬件合作)。由于当今处理器的复杂性,测量这一点既困难又昂贵——更不用说测量的意义(由于非线性执行和各种其他很酷的东西)很难解释——因此很难计算一个 (对特定代码部分执行时间的最坏或常见)情况估计。

    有点题外话,但 Ada 在这里在语言级别提供了一组更严格的功能,这对您没有帮助,但您可以弄清楚这些 Ada 要求是如何在 Linux 中实现的。 Ada 语言规范在提供基本原理文档方面是独一无二的,请参阅real-time preemptive abort 部分作为出发点。

    【讨论】:

      【解决方案3】:

      我想要的解决方案突然出现在我身上:goto!我将在我希望限制的函数之后设置一个跳转点,设置一个计时器并在处理 SIG*ALRM 的信号处理程序中简单地跳转到函数之后的指令。

      【讨论】:

      • 如果这就是你想要的效果,那你为什么不能用sigsetjmp()/siglongjmp()呢?注意到goto 实际上并不能跨函数边界工作。
      • 很对,goto 确实只有函数作用域。虽然使用 *jmp 有一些不足之处,但它主要让我到达了我想去的地方。我根本没有想到,因为“Goto 是有害的”已经在我脑海中敲打了这么久。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-23
      • 2011-08-29
      • 1970-01-01
      • 2010-11-13
      • 2021-07-12
      相关资源
      最近更新 更多