如果我使用create_timer
字段中SIGEV_THREAD
字段中存储的sigev_notify
常量调用sigevent
,那么当计时器事件发生时,我的sigev_notify_function
回调将被调用。
在我的回调函数中调用timer_delete
是否有任何隐藏的含义或不良副作用?
具体问题
我最初的想法是它应该没问题。但是,我并不完全理解在幕后操作的机制,我担心如果在处理完成之前删除了计时器及其相关结构,那么回调线程的正确清理和信号的处理。
另一位SO用户问this question,其实质上是说,“在致电timer_create
后我是否真的需要删除我的计时器?我的回答是响亮的是。然后他在评论中提出了一个后续问题:“从定时器回调函数中做到这一点是否可以?”我对此没有一个好的答案。
答案 0 :(得分:1)
根据sigevent(7)
,当您使用SIGEV_THREAD
时,回调将按以下方式执行:
通过调用
sigev_notify_function
来通知该过程,就像“它是”一样 新线程的启动功能。 (在实施中 这里的可能性是每个计时器通知都可能导致 创建新线程,或创建单个线程 收到所有通知。)
因此,就您(程序员)所知,您的通知函数正在新线程的上下文中执行,不在标准信号处理程序例程的上下文中,该例程会中断另一个线程的执行。因此,异步信号安全功能的规则不适用,与Basile的答案中提到的相反,因此当您使用SIGEV_THREAD
与计时器时,您可以在通知功能中执行您的心愿。这包括致电timer_delete
删除timer_t
。
答案 1 :(得分:0)
看起来原则上不允许至少在Linux上调用timer_create
或timer_delete
。 signal(7)仅允许从信号处理程序直接或间接调用 async-signal-safe 函数,奇怪的是timer_create
和timer_delete
未列在其中(也许这是一个拼写错误,它们都应该列为异步信号安全,因为timer_create(2)和timer_delete(2)都位于手册页的第2部分,并出现在syscalls(2)中)
请注意,POSIX signal concepts页面不会在信号处理程序中列出timer_create
。我想在某些操作系统上,这些定时器函数可能完全在C库中实现(不在内核中)。
我的猜测(因为timer_create
和timer_delete
是<asm/unistd.h>
上列出的syscall ){em> {{1事实上,timer_create
是异步信号安全的,因此可以从 Linux 信号处理程序调用。其他POSIX实现可能会出错。