Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C pthread_kill异步信号在Linux上安全吗?_C_Linux_Signals - Fatal编程技术网

C pthread_kill异步信号在Linux上安全吗?

C pthread_kill异步信号在Linux上安全吗?,c,linux,signals,C,Linux,Signals,OpenGroup Unix specpthread\u kill()是异步信号安全的。但是Linux并没有在相关章节中列出这个函数 那么,在Linux上的信号处理程序中调用pthread\u kill安全吗?我知道它是使用tgkill()实现的(这是安全的…但这不会自动使pthread\u kill()也安全) 一些背景: 使用O_ASYNC/F_SETOWN\u EX/F_SETSIG将SIGRTMIN信号定向到I/O就绪时的特定线程 不幸的是,当实时信号队列已满时,Linux将恢复向整个

OpenGroup Unix spec
pthread\u kill()
是异步信号安全的。但是Linux并没有在相关章节中列出这个函数

那么,在Linux上的信号处理程序中调用
pthread\u kill
安全吗?我知道它是使用
tgkill()
实现的(这是安全的…但这不会自动使
pthread\u kill()
也安全)

一些背景:

  • 使用
    O_ASYNC/F_SETOWN\u EX/F_SETSIG
    将SIGRTMIN信号定向到I/O就绪时的特定线程
  • 不幸的是,当实时信号队列已满时,Linux将恢复向整个进程提供SIGIO
  • 为纠正此错误,安装了SIGIO处理程序,该处理程序将该信号转发回指定线程(该线程阻止SIGIO并在信号处理循环中使用
    sigwaitinfo()
编辑:信号处理线程将收到的SIGIO视为“我们有活动,但不知道在哪里--检查每个文件描述符”。不理想,但总比完全忽略信号要好


编辑2:不得不对设计进行一些更新(出于某种深不可测的原因,我认为SIGIO是一个实时信号)。

这里总结了克雷格·埃斯蒂的答案(谢谢,哥们!):

在所有(最近的)手册页中,
pthread\u kill
被列为异步信号安全。glibc sources中有一条评论称,如果出现
fork()
,它是不安全的,因此如果你感到偏执,你可以使用
tgkill(getpid(),)

所以,是的,
pthread\u kill
tgkill
都应该可以


在我的CentOS 7上,
man
没有将任何一个列为安全的,但可能是因为它太旧了。

您发布的第一个链接直接在异步信号安全部分列出了
pthread\u kill
。但是,我会将源代码拉到
glibc
pthread\u kill
中的注释与doc相反。一条注释:TCB中的PID字段可以临时更改(在fork中)。但这不能影响这里的代码。由于此函数必须在线程执行fork时调用,因此必须在信号处理程序中调用。但是这是不允许的,pthread_kill不能保证是异步安全的?如果它们不是磁盘上的文件,那么像其他人一样使用
poll()
怎么样?@JohnZwinck OP之前有一个问题[自删除后]是关于
SIGIO
用法的。出于某种[未指明的]原因,他无法阻止除一个线程之外的所有线程中的信号。然后我建议他将所有的
sigwaitinfo
替换为
poll
。我不打算再次提及它[以免我感到恼火],但既然你已经提出了它,我将重申,
poll
方法更快、更简单,并且不会溢出R/t sigqueue[不再需要它]。CentOS使用
glibc
。要解决此问题,请在“I/O线程”的init处执行:
glob\u iotid=gettid()
。然后,在信号处理程序中,执行
tgkill(…,glob\u iotid,sig)
。这就避免了CentOS/Fedora
man signal safety
pthread_kill
列为安全的模糊性。在
glibc
源代码中,它讨论的是如何使用
fork
。因此,如果您没有使用
fork
,我对实际代码本身的看法是,尽管有注释,它仍然可以工作。