如何限制C/POSIX中函数的执行时间?

发布于 2024-09-19 18:30:38 字数 1195 浏览 25 评论 0原文

与此问题类似,我我想限制 C 中函数的执行时间——最好是微秒级的精度。我想 C++ 异常可以用来实现类似于 这个 Python 解决方案。虽然它并不理想,但这种方法在普通 C 中是完全不可用的。

那么我想知道,在 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;
}

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

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

Similar to this question, I'd like to limit the execution time of a function--preferably with microsecond accuracy--in C. I imagine that C++ exceptions could be used to achieve a result similar to this Python solution. Though it's not ideal, such an approach is wholly unavailable in plain C.

I wonder, then, how might I interrupt the execution of a function after a certain time interval in C on a Posix system? For relatively simple situations a bit of silly business works just fine, but that adds a fair amount of code orthogonal to the problem solution. Let's say I have a function like so:

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

I want to run run boil on an egg*, interrupting it every 50μs to check do something like so:

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;
}

I realize that pthreads could be used to do this, but I'm rather more interested in avoiding their use. I could switch between ucontext_t's in a SIGALRM handler, but the POSIX standard notes that the use of setcontext/swapcontext is not to be used in a signal handler and, indeed, I note differing behaviors between Linux and Solaris systems when doing so.

Is this effect possible to achieve? If so, in a portable manner?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

寻找一个思念的角度 2024-09-26 18:30:39

请注意,您在这里寻找的一般功能称为“成本执行”。例如,请参阅 Wellings梁 等等人的好书。上面的答案集中在用户空间中实现它;一些 RTOS 或语言支持它(不包括 Linux)作为通用机制。

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

有点题外话,但 Ada 在语言层面提供了一套更严格的功能,这对你没有帮助,但你可以弄清楚这些 Ada 要求是如何在 Linux 中实现的。 Ada 语言规范在提供基本原理文档方面是独一无二的,请参阅 实时抢先中止作为出发点。

Just to note that the general capability you're looking for here is called cost enforcement. For example see this article by Wellings or in Leung, et. al.'s great book. The answers above are focused on achieving it in userspace; some RTOS or languages support it (not linux) as a general mechanism.

One example OS that provides this is the AUTOSAR OS (spec linked). Note that this OS provides execution time enforcement, which is slightly different from deadline enforcement. Execution time enforcement keeps getting harder, as it relies on some ability to measure the actual cost expended (usually with hardware cooperation). With the complexity of today's processors, it's difficult and costly to measure this — not to mention that the meaning of the measurements (due to nonlinear execution and all sorts of other cool stuff) are hard to interpret — and thus difficult event to compute a (worst- or common-) case estimate of a particular section of code's execution time.

Slightly off-topic, but Ada provides a more rigorous set of capabilities at the language level here, which doesn't help you, but you could figure out how these Ada requirements have been implemented in Linux. The Ada language spec is unique in providing a rationale document, see the section on real-time preemptive abort as a departure point.

酒几许 2024-09-26 18:30:39

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

The solution I desire suddenly occurs to me: goto! I'll setup a jump point just after the function I wish to limit, set a timer and in the signal handler which deals with the SIG*ALRM simply jump to the instruction after the function.

独木成林 2024-09-26 18:30:38

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

You can either use threads, or have the function poll a timer (or a global variable set by SIGALRM handler), then save its state and exit when the allotted time has expired. Use of ucontext_t is deprecated and should never be used in new code, at all, much less from signal handlers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文