当一个线程forks()时,其他线程会发生什么?

时间:2012-04-09 22:43:51

标签: c++ multithreading pthreads fork

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

似乎线程没有跟随。在我的情况下,我正在尝试创建一个守护进程,我使用fork()与父进程deamonize它。但是,在通过代码的新路径中,我在fork之前创建了一些线程,之后又创建了一些线程。有没有一种简单的方法可以将线程的所有权更改为新的分叉进程,而不是在fork之后移动我的所有线程创建?

5 个答案:

答案 0 :(得分:24)

无。只有调用fork()的线程才会重复。子进程必须启动任何新线程。父母的线索是孤立的。

答案 1 :(得分:3)

在POSIX中,当多线程进程分叉时,子进程看起来就像是父进程的副本,但是其中所有线程都停在其轨道上并消失了。

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

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

使用互斥锁的任何正确编写的程序模块(尤其是可重用的中间件)必须调用pthread_atfork来注册一些处理程序,以便在进程调用fork时它不会出错。

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

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

答案 2 :(得分:3)

分叉线程通常非常糟糕。分叉进程应该是父进程的完整副本,除非线程不是。有一个函数pthread_atfork()有时会有所帮助。如果您必须分叉一个主题,最好是在exec()之后立即致电fork()

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

来自fork()文档:

  

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

答案 3 :(得分:2)

引自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).

所以we should think twice before using them

答案 4 :(得分:0)

没有,除非有人碰巧被运行新进程的线程抢占了。