gpt4 book ai didi

c - timer_create 如何在第一个计时器到期后停止递归线程函数调用?

转载 作者:太空狗 更新时间:2023-10-29 11:39:49 25 4
gpt4 key购买 nike

我使用简单的“timer_create”创建了一个计时器。计时器是使用 SIGEV_THREAD 创建的。即当定时器超时时,有一个定时器线程函数的调用。

timer_create 是如何工作的,假设假设:expiry=3 秒并且定时器间隔为 1 ns,那么定时器会每 1 ns 计时一次,直到 expiry 到达.一旦计时器到期,从那个实例开始,它会在每 1 ns(计时器间隔)后继续点击计时器线程函数。并继续为每次点击创建一个线程,直到计时器被删除。

我不希望这种情况发生,我希望一旦计时器到期,它应该只触发线程函数一次。

我怎样才能做到这一点?我们可以在 timer_create 中添加任何选项吗?如果不是任何其他计时器 API?

提前致谢

最佳答案

我认为这是 POSIX 计时器的 glibc 实现中的一个实现缺陷。对于实时使用至关重要的 timer_getoverrun 函数肯定无法在 glibc 实现中工作,因为它从内核返回“当前”过期的超限计数,但是当多次过期时事件并行运行,“当前”没有意义。资源耗尽和丢弃的过期事件也存在严重问题,这使得实现无法用于实时目的。例如,在 nptl/sysdeps/unix/sysv/linux/timer_routines.c 中:

struct thread_start_data *td = malloc (sizeof (*td));

/* There is not much we can do if the allocation fails. */
...

sigevent 的 Linux 手册页中,您会看到 SIGEV_THREAD:

Among the implementation possibilities here are that each timer notification could result in the creation of a new thread, or that a single thread is created to receive all notifications.

后者是唯一可以提供正确的实时语义的选择,但出于某种原因,glibc 没有采用这种选择。

这是一个可能的解决方法:

选择一个实时信号,在创建任何线程之前阻塞该信号,并设置您的计时器以通过 SIGEV_SIGNAL 使用该信号。现在,创建一个线程来处理您的计时器,并在 sigwaitinfo 上循环,然后在每次返回时调用您的处理函数。这实际上是 glibc 应该 使用的 SIGEV_THREAD 的一种可能实现(也是最正确的实现)。

另一种可能性:POSIX 中只有一个同步相关的、非系统调用调用的、异步信号安全的函数:sem_post。因此,有可能使信号处理程序(与从 sigwaitinfo 获取信号相反)与另一个线程同步以传递计时器事件。但是我还没有弄清楚细节,看起来可能还是很难或者不可能。

关于c - timer_create 如何在第一个计时器到期后停止递归线程函数调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5513597/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com