22

在使用 pthread 的 C++ 中,如果您的一个线程调用 fork,您的其他线程会发生什么?

似乎线程没有跟随。就我而言,我正在尝试创建一个守护进程,并使用 fork() 与父级退出来解除它。但是,在代码的新路径中,我在分叉之前和之后创建了一些线程。有没有一种简单的方法可以将线程的所有权更改为新的分叉进程,而不是在分叉之后移动我的所有线程创建?

4

5 回答 5

26

没有。只有调用 fork() 的线程才会重复。子进程必须启动任何新线程。父母线程被单独留下。

于 2012-04-09T22:45:58.413 回答
12

在 POSIX 中,当多线程进程分叉时,子进程看起来与父进程完全相同,但其中所有线程都停止在其轨道上并消失了。

如果线程持有锁,这是非常糟糕的。

出于这个原因,有一种称为粗略的机制pthread_atfork,您可以在其中为这种情况注册处理程序。

任何使用互斥锁的正确编写的程序模块(尤其是可重用的中间件)都必须调用pthread_atfork以注册一些处理程序,以便在进程碰巧调用fork.

除了互斥锁之外,线程还可以拥有其他资源,例如隐藏在pthread_setspecific其中的特定于线程的数据只能由线程访问(并且线程负责通过析构函数对其进行清理)。

在子进程中,没有这样的析构函数运行。地址空间被复制,但线程及其线程特定值不存在,因此内存在子进程中泄漏。这也可以并且应该由处理pthread_atfork程序处理。

于 2012-04-09T23:02:10.347 回答
4

引用自http://thorstenball.com/blog/2014/10/13/why-threads-cant-fork/

If we call fork(2) in a multi-threaded environment the thread doing the call is now the main-thread in the new process and all the other threads, which ran in the parent process, are dead. And everything they did was left exactly as it was just before the call to fork(2).

所以我们在使用它们之前应该三思而后行

于 2014-10-14T08:01:38.350 回答
3

分叉一个线程通常是非常糟糕的。分叉的进程应该是父进程的完整副本,但它不是线程。有一个功能pthread_atfork()有时会有所帮助。如果你必须分叉一个线程,最好exec()fork().

我建议您阅读 POSIX 开发人员在文档中的警告fork()pthread_atfork()(参见http://pubs.opengroup.org/onlinepubs/007904975/functions/fork.htmlhttp://pubs.opengroup.org/onlinepubs/007904975 /functions/pthread_atfork.html)。

fork()文档中:

因此,该fork()函数仅用于运行新程序,并且在调用和调用函数之间需要某些资源的调用函数的效果fork()exec未定义的。

于 2012-04-09T23:02:20.323 回答
-1

什么都没有,除非碰巧被运行新进程的线程抢占。

于 2012-04-09T22:47:21.287 回答