如果我有一个运行线程的程序并fork()
在基于UNIX的系统上调用,是否复制了线程?我知道当前进程的虚拟内存将1:1复制到新进程。我知道线程在进程的虚拟内存中有自己的堆栈。因此,至少也应该复制线程堆栈。但是,我不知道线程中是否还有其他不驻留在虚拟内存中并且因此不会被复制的线程。如果没有,这两个进程是共享线程还是它们是独立副本?
如果我有一个运行线程的程序并fork()
在基于UNIX的系统上调用,是否复制了线程?我知道当前进程的虚拟内存将1:1复制到新进程。我知道线程在进程的虚拟内存中有自己的堆栈。因此,至少也应该复制线程堆栈。但是,我不知道线程中是否还有其他不驻留在虚拟内存中并且因此不会被复制的线程。如果没有,这两个进程是共享线程还是它们是独立副本?
Answers:
线程不会复制到fork()
。POSIX规范说(强调是我的):
fork-创建一个新过程
进程应使用单个线程创建。如果多线程进程调用fork(),则新进程应包含调用线程的副本及其整个地址空间,可能包括互斥体和其他资源的状态。因此,为避免错误,子进程只能执行异步信号安全操作,直到调用exec函数之一为止。
为了解决这个问题,存在一个pthread_atfork()
帮助功能。
人叉:
子进程由一个线程创建,该线程称为fork()。父级的整个虚拟地址空间都在子级中复制,包括互斥体,条件变量和其他pthreads对象的状态;使用pthread_atfork(3)可能有助于解决可能引起的问题。
摘自The Open Group Base Specification第7期,2018年版的分支:
进程应使用单个线程创建。如果多线程进程调用fork(),则新进程应包含调用线程的副本及其整个地址空间,其中可能包括互斥体和其他资源的状态。因此,为避免错误,子进程只能执行异步信号安全操作,直到调用exec函数之一为止。
当应用程序从信号处理程序调用fork()时,并且pthread_atfork()注册的任何fork处理程序调用的函数都不是异步信号安全的,该行为是不确定的。