如何在C/POSIX中限制函数的执行时间? 类似于此,我希望在C中限制函数的执行时间——最好是微秒级的精度。我想C++异常可以用来实现类似于Python解决方案的结果。虽然这种方法并不理想,但在普通C语言中是完全不可用的

如何在C/POSIX中限制函数的执行时间? 类似于此,我希望在C中限制函数的执行时间——最好是微秒级的精度。我想C++异常可以用来实现类似于Python解决方案的结果。虽然这种方法并不理想,但在普通C语言中是完全不可用的,c,posix,real-time,portability,preemption,C,Posix,Real Time,Portability,Preemption,那么,我想知道在Posix系统上,在C语言中经过一定的时间间隔后,如何中断函数的执行?对于相对简单的情况,一点工作就可以了,但这增加了大量与问题解决方案正交的代码。假设我有这样一个函数: void boil(egg *e) { while (true) do_boil(e); } 我想在鸡蛋上运行沸腾*,每50μs中断一次,以检查是否执行以下操作: egg *e = init_egg(); while (true) { preempt_in(50, (void) (*b

那么,我想知道在Posix系统上,在C语言中经过一定的时间间隔后,如何中断函数的执行?对于相对简单的情况,一点工作就可以了,但这增加了大量与问题解决方案正交的代码。假设我有这样一个函数:

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来实现这一点,但我更感兴趣的是避免使用pthread。我可以在SIGALRM处理程序中的ucontext_t之间切换,但POSIX标准指出,setcontext/swapcontext的使用不适用于信号处理程序,事实上,我注意到Linux和Solaris系统在这样做时的不同行为


这种效果可能达到吗?如果是这样,您可以使用线程,或者让函数轮询计时器(或由
SIGALRM
处理程序设置的全局变量),然后保存其状态,并在分配的时间过期时退出。不推荐使用ucontext\t,不应在新代码中使用,更不要说在信号处理程序中使用。

我突然想到了我想要的解决方案:goto!我将在我想要限制的函数之后设置一个跳转点,设置一个计时器,并在处理SIG*ALRM的信号处理程序中直接跳转到函数之后的指令。

请注意,您在这里寻找的一般功能称为成本强制。例如,请参见本文作者或作者。上面的答案集中于在用户空间中实现它;一些RTO或语言支持它(而不是linux)作为一种通用机制

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


有点离题,但是Ada在这里提供了一组更严格的语言级别的功能,这对您没有帮助,但是您可以了解这些Ada要求是如何在Linux中实现的。Ada语言规范在提供基本原理文档方面是独一无二的,请参见作为出发点的章节。

引用
ucontext\t
弃用?我认为相关的功能没有得到广泛的实现。快速的google for
ucontext deprecated
会发现一些关于特定供应商的信息,尤其是苹果,将它们标记为deprecated。至于官方的反对意见,我没有立即引用,但我似乎记得SUSv3反对部分或全部功能,因为C99制作了一些它需要的未定义行为的指针强制转换构造。不过,我必须再看一次,以确定……那么,我假设你的答案是否定的。在你的估计中,我要么进行投票,要么引入线程。如果这是你想要的效果,那么你为什么不能直接使用
sigsetjmp()
/
siglongjmp()
?请注意,
goto
实际上并不跨功能边界工作。完全正确,goto只有功能范围。虽然*jmp的使用有一些不足之处,但它主要帮助我达到我想要达到的目的。我根本没有想到这一点,因为“Goto是有害的”已经在我脑子里敲了很久了。