如何调用' pthread_atfork() '注册的手动fork处理程序?



我在glibc中使用vfork(),根据vfork()的手册页:

使用pthread_atfork(3)建立的Fork处理程序不被调用当一个多线程程序使用NPTL线程库时调用vfork()。类中调用Fork处理程序程序使用LinuxThreads线程库。

在NPTL上分叉处理程序没有被调用。在我的特殊情况下,我需要使用此保护因此,调用fork处理程序的方式将与调用fork()时相同。

是否有一种方法可以使pthread库调用已注册的处理程序,甚至手动调用它们?

我想到使用clone(),因为它提供了更精确的克隆进程控制,但它也避免了分叉处理程序:

使用pthread_atfork(3)注册的处理程序不执行在克隆呼叫中。

还可以阅读如何重置pthread_atfork注册的处理程序-在我的情况下,我不想删除处理程序,而只想调用它们。

谢谢。

是否有办法使pthread库调用已注册的处理程序,甚至手动调用它们?

如果您成功地做到了这一点,您的程序将变成损坏。有一个原因pthread_atfork处理程序没有在vfork上调用。

pthread_atfork处理程序的典型用法是保证父进程中持有的任何锁在fork之后在子进程和父进程中都处于一致状态。

如果没有处理程序,假设线程T1持有锁L,线程T2调用fork。因为只有T2会被复制到子进程中,所以L将永远处于锁定状态。如果T2需要这个锁(假设它是malloc锁),T2将死锁(T1不存在于子进程中)。

解决方案:pthread_atfork处理程序。在父进程中prepare()将获取L,parent()child()处理程序将分别在父进程和子进程中解锁L自己的实例。一切都很幸福1


现在考虑如果在vfork之后做同样的事情会发生什么。prepare()按预期获取L,但是当您调用parent()child()时,它们会解锁L的同一个实例(因为父进程和子进程共享内存)。因此,L被解锁两次,破坏了它!


1在实践中,在多线程程序中调用forkvfork是充满危险的,并且在任意库存在的情况下安全地执行此操作几乎是不可能的。

相关内容

  • 没有找到相关文章