我对在多线程进程上使用 fork 有疑问。如果一个进程有多个线程(已经使用 pthread_create 创建并执行了 pthread_join)并且我调用了 fork,它会复制分配给子进程中线程的相同函数还是创建一个可以重新分配函数的空间?
1 回答
仔细阅读 POSIX 所说的内容fork()和线程。尤其是:
- 应使用单个线程创建进程。如果多线程进程调用
fork(),新进程应包含调用线程及其整个地址空间的副本,可能包括互斥锁和其他资源的状态。因此,为避免错误,子进程只能执行异步信号安全操作,直到调用其中一个 exec 函数。
子进程将在调用线程的上下文中运行一个线程。原始进程的其他部分可能被不再存在的线程捆绑(例如,互斥锁可能被锁定)。
基本原理部分(在链接页面的下方)说:
POSIX 程序员调用
fork(). 一个原因是在同一个程序中创建一个新的控制线程(这最初只能在 POSIX 中通过创建一个新进程来实现);另一种是创建一个运行不同程序的新进程。在后一种情况下,调用fork()之后很快就会调用其中一个exec函数。在多线程世界中工作的一般问题
fork()是如何处理所有线程。有两种选择。一种是将所有线程复制到新进程中。这会导致程序员或实现处理在系统调用上挂起的线程或可能即将执行不应在新进程中执行的系统调用的线程。另一种选择是仅复制调用fork(). 这造成了进程本地资源的状态通常保存在进程内存中的困难。如果没有调用的线程fork()持有资源,则该资源永远不会在子进程中释放,因为其任务是释放资源的线程在子进程中不存在。当程序员编写多线程程序时,函数
fork()提供了第一个描述的用法,即在同一程序中创建新线程pthread_create()。因此,该fork()函数仅用于运行新程序,并且在调用fork()和调用 exec 函数之间调用需要某些资源的函数的效果是未定义的。