可以在事件处理函数中删除POSIX计时器吗?

时间:2015-04-22 16:17:14

标签: c linux

问题

如果我使用create_timer字段中SIGEV_THREAD字段中存储的sigev_notify常量调用sigevent,那么当计时器事件发生时,我的sigev_notify_function回调将被调用。

在我的回调函数中调用timer_delete 是否有任何隐藏的含义或不良副作用?

具体问题

我最初的想法是它应该没问题。但是,我并不完全理解在幕后操作的机制,我担心如果在处理完成之前删除了计时器及其相关结构,那么回调线程的正确清理和信号的处理。

背景

另一位SO用户问this question,其实质上是说,“在致电timer_create后我是否真的需要删除我的计时器?我的回答是响亮的。然后他在评论中提出了一个后续问题:“从定时器回调函数中做到这一点是否可以?”我对此没有一个好的答案。

2 个答案:

答案 0 :(得分:1)

根据sigevent(7),当您使用SIGEV_THREAD时,回调将按以下方式执行:

  

通过调用sigev_notify_function来通知该过程,就像“它是”一样   新线程的启动功能。 (在实施中   这里的可能性是每个计时器通知都可能导致   创建新线程,或创建单个线程   收到所有通知。)

因此,就您(程序员)所知,您的通知函数正在新线程的上下文中执行,在标准信号处理程序例程的上​​下文中,该例程会中断另一个线程的执行。因此,异步信号安全功能的规则不适用,与Basile的答案中提到的相反,因此当您使用SIGEV_THREAD与计时器时,您可以在通知功能中执行您的心愿。这包括致电timer_delete删除timer_t

答案 1 :(得分:0)

看起来原则上不允许至少在Linux上调用timer_createtimer_deletesignal(7)仅允许从信号处理程序直接或间接调用 async-signal-safe 函数,奇怪的是timer_createtimer_delete未列在其中(也许这是一个拼写错误,它们都应该列为异步信号安全,因为timer_create(2)timer_delete(2)都位于手册页的第2部分,并出现在syscalls(2)中)

请注意,POSIX signal concepts页面不会在信号处理程序中列出timer_create。我想在某些操作系统上,这些定时器函数可能完全在C库中实现(不在内核中)。

我的猜测(因为timer_createtimer_delete<asm/unistd.h>上列出的syscall ){em> {{1事实上,timer_create 是异步信号安全的,因此可以从 Linux 信号处理程序调用。其他POSIX实现可能会出错。