Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.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 fork(应该)在线程程序中不受信号处理程序的影响吗?_C_Pthreads_Deadlock_Fork_Signals - Fatal编程技术网

C fork(应该)在线程程序中不受信号处理程序的影响吗?

C fork(应该)在线程程序中不受信号处理程序的影响吗?,c,pthreads,deadlock,fork,signals,C,Pthreads,Deadlock,Fork,Signals,我真的不确定POSIX在线程和信号存在的情况下对fork安全性的要求fork被列为异步信号安全函数之一,但如果库代码可能已注册了非异步信号安全的pthread\u atfork处理程序,这是否会否定fork的安全性?答案是否取决于信号处理程序运行的线程是否在使用AtDoc处理程序所需的资源的中间?或者用另一种方式说,如果atfork处理程序使用同步资源(互斥体等),但是fork是从一个信号处理程序调用的,该信号处理程序在一个从未访问这些资源的线程中执行,那么该程序符合要求吗 基于这个问题,如果使

我真的不确定POSIX在线程和信号存在的情况下对
fork
安全性的要求
fork
被列为异步信号安全函数之一,但如果库代码可能已注册了非异步信号安全的
pthread\u atfork
处理程序,这是否会否定
fork
的安全性?答案是否取决于信号处理程序运行的线程是否在使用AtDoc处理程序所需的资源的中间?或者用另一种方式说,如果atfork处理程序使用同步资源(互斥体等),但是
fork
是从一个信号处理程序调用的,该信号处理程序在一个从未访问这些资源的线程中执行,那么该程序符合要求吗

基于这个问题,如果使用
pthread_atfork
建议的惯用法在系统库内部实现“线程安全”分叉(获取prefork处理程序中的所有锁,并释放父和子postfork处理程序中的所有锁),那么,在线程程序中从信号处理程序使用fork是否安全?不可能处理信号的线程是否在调用<代码> MALLC/<代码>或<代码> fOpen< /COD> >代码> fCXS/<代码>,并持有全局锁,导致在<代码> For < /C> >死锁>

最后,即使在信号处理程序中
fork
是安全的,在信号处理程序中
fork
然后从信号处理程序返回是否安全,或者在信号处理程序中调用
fork
是否总是需要在信号处理程序返回之前调用
\u exit
exec
函数族中的一个?

在信号处理程序中使用fork()应该可以

pthread_atfork听起来是个坏主意

为了回答您最初的问题,pthread无法保证调用任何pthread_atfork函数的安全性是异步信号安全的,因为内核的信号实现使得这一点不可能实现

哦,如果您在信号处理程序中分叉,则不允许子级从信号处理程序返回。这是未定义的。

据我所知,它使用信号状态临界部分来确保分叉过程不会被信号中断

  ss = _hurd_self_sigstate ();
  __spin_lock (&ss->critical_section_lock);
作为在关键段锁定后执行的
pthread\u atfork
处理程序,它们会自动成为信号安全的

也许我错了,我会感谢你的更正。

这里

fork被列为异步信号安全型,因此可以使用它

POSIX

下表将从“打开”菜单中删除 组基本规范[开放组 定义了一组函数,这些函数 异步信号是安全的。 应用程序可以调用这些 功能,不受限制,来自 信号处理器

异步信号安全功能

fork()


尽我所能回答所有的子问题;我很抱歉,其中有些内容比理想情况下更模糊:

如果有 库代码具有 已注册的pthread_atfork处理程序 不是异步信号安全的,是吗 这否定了叉子的安全性

对。报告明确提到这一点:

   When the application calls fork() from a signal handler and any of the
   fork handlers registered by pthread_atfork() calls a function that is
   not asynch-signal-safe, the behavior is undefined.
当然,这意味着您不能实际使用
pthread_atfork()
来达到使多线程库对相信它们是单线程的进程透明的目的,因为pthread同步函数都不是异步信号安全的;这是规范中的一个缺陷,请参见(搜索“L16723”)

做 答案取决于 执行信号处理程序的线程 跑步可能在中间。 使用atfork支持的资源 你需要什么?或者说另一种说法 如果atfork处理程序使用 同步资源(互斥体, 等等),但fork是从 在 从不访问这些文件的线程 资源,程序是否符合要求

严格地说,答案是否定的,因为根据规范,函数要么是异步信号安全的,要么不是;没有“在某些情况下安全”的概念。在实践中,您可能会侥幸逃脱,但您很容易受到笨重但正确的实现的攻击,该实现没有按照您期望的方式对其资源进行分区

基于这个问题,如果 实现了“线程安全”分叉 在系统库内部使用 pthread_atfork建议的习语 (获取预工作中的所有锁 处理程序并释放两个中的所有锁 父和子postfork 那么fork对你来说安全吗 从线程中的信号处理程序使用 节目?难道这不可能吗 处理信号的线程可能处于 调用malloc或 fopen/fclose和举行全球会议 锁定,导致进程中出现死锁 叉子

如果它是以这种方式实现的,那么您是对的,来自信号处理程序的
fork()
将永远不会安全,因为如果调用线程已经持有锁,尝试获取锁可能会死锁。但这意味着使用这种方法的实现将不符合要求

以glibc为例,它并没有做到这一点——相反,它采取了两种方法:首先,它确实获得的锁是递归的(因此,如果当前线程已经拥有它们,它们的锁计数将简单地增加);此外,在子进程中,它只是单方面地覆盖所有锁—请参阅
nptl/sysdeps/unix/sysv/linux/fork.c
中的摘录:

  /* Reset the file list.  These are recursive mutexes.  */
  fresetlockfiles ();

  /* Reset locks in the I/O code.  */
  _IO_list_resetlock ();

  /* Reset the lock the dynamic loader uses to protect its data.  */
  __rtld_lock_initialize (GL(dl_load_lock));
其中,
resetlock
lock\u initialize
函数最终调用glibc的内部等价物
pthread\u mutex\u init()
,有效地重置互斥体,而不考虑任何等待者

我认为理论是,由奥塔尼