关于fork子进程问题

drinker_linux 2010-03-26 11:08:08
请问fork子进程会是父进程的一个复制品,例如,子进程获得父进程数据空间、堆和栈的复制品。那么请问,如果主进程里有三个线程,这三个线程是分别有自己的堆栈的,如果一个子进程是从这三个线中其中一个fork出来的话,那么这个子进程是复制当前这个线程的数据空间和堆栈呢,还是整个这个进程的呢?困惑,谢谢!
...全文
338 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
小南家的青蛙 2010-04-18
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 do_fork 的回复:]

APUE说,fork只会copy调用fork的那个线程.

Inside the child process, only one thread exists. It is made from a copy of the
thread that called fork in the parent. If the threads in the parent process hold
any……
[/Quote]
尽信书不如无书
各个平台fork的语义有细小的差别,APUE写作的年代相对来说比较早,有情况可能照不到现在的情况
有时间的话可以参考一下ACE在进程派生这块的源码,就知道各个平台有哪些不同了
mymtom 2010-04-18
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 babyblue_963 的回复:]
引用 12 楼 yanran_hill 的回复:

大部分unix系统,在调用fork后,都是复制所有的线程到主进程,不过我记得似乎有一些操作系统(好像是新版的支持posix的solaris记不清了),也支持只复制当前线程,即只复制一个线程,由用户来保证新创建的子进程的线程安全性,如果这时子进程中存在其它线程锁定的mutex等东西,要由用户自己解决资源问题.

solaris有forkon……
[/Quote]
我查了Solaris手册,证实我说错了。
Solaris提供fork fork1 forkall三个系统调用。可以复制一个或者全部线程。
yzx714 2010-04-18
  • 打赏
  • 举报
回复
POSIX中的fork只复制调用fork的那个线程吧,还有个复制所有的forkall
do_fork 2010-04-18
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 babyblue_963 的回复:]

引用 18 楼 do_fork 的回复:

APUE说,fork只会copy调用fork的那个线程.

Inside the child process, only one thread exists. It is made from a copy of the
thread that called fork in the parent. If the threads in the p……
[/Quote]

APUE当前版是2005年出的,没有那么古老,
描述的平台也增加了linux和mac

细微差别会有,但是大体上都应遵循POSIX.1-2001.跟SVr4和4.3BSD相近
do_fork 2010-04-17
  • 打赏
  • 举报
回复
APUE说,fork只会copy调用fork的那个线程.

Inside the child process, only one thread exists. It is made from a copy of the
thread that called fork in the parent. If the threads in the parent process hold
any locks, the locks will also be held in the child process. The problem is that
the child process doesn't contain copies of the threads holding the locks, so
there is no way for the child to know which locks are held and need to be unlocked.
liudanking 2010-04-17
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 hairetz 的回复:]
引用楼主 drinker_linux 的回复:
请问fork子进程会是父进程的一个复制品,例如,子进程获得父进程数据空间、堆和栈的复制品。那么请问,如果主进程里有三个线程,这三个线程是分别有自己的堆栈的,如果一个子进程是从这三个线中其中一个fork出来的话,那么这个子进程是复制当前这个线程的数据空间和堆栈呢,还是整个这个进程的呢?困惑,谢谢!


重复一次,完全复制(不考虑写时复制那些具体……
[/Quote]
同意,fork就是一个进程的复制过程。
小南家的青蛙 2010-04-17
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 yanran_hill 的回复:]

大部分unix系统,在调用fork后,都是复制所有的线程到主进程,不过我记得似乎有一些操作系统(好像是新版的支持posix的solaris记不清了),也支持只复制当前线程,即只复制一个线程,由用户来保证新创建的子进程的线程安全性,如果这时子进程中存在其它线程锁定的mutex等东西,要由用户自己解决资源问题.
[/Quote]
solaris有forkone语义,不同的平台在处理fork的时候略微有所不同,用到的时候需要man一下
个人理解,最好在父进程单线程的情况下fork子进程,这样是最简单的情况,省了不少麻烦事,而且调试起来也容易点
ForestDB 2010-04-17
  • 打赏
  • 举报
回复
帮顶。
mymtom 2010-04-16
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 yanran_hill 的回复:]

大部分unix系统,在调用fork后,都是复制所有的线程到主进程,不过我记得似乎有一些操作系统(好像是新版的支持posix的solaris记不清了),也支持只复制当前线程,即只复制一个线程,由用户来保证新创建的子进程的线程安全性,如果这时子进程中存在其它线程锁定的mutex等东西,要由用户自己解决资源问题.
[/Quote]
这种说法有依据吗?
举个简单的例子
进程A的线程A1调用fork时,线程A2正在fgets(),
fork出的新进程B的线程B1从fork返回,这个没有问题;难么线程A2对应的线程B2应该是什么状态?
这个问题根本无法解决,也就无法实现什么“复制所有的线程父进程”。
  • 打赏
  • 举报
回复
[Quote=引用楼主 drinker_linux 的回复:]
请问fork子进程会是父进程的一个复制品,例如,子进程获得父进程数据空间、堆和栈的复制品。那么请问,如果主进程里有三个线程,这三个线程是分别有自己的堆栈的,如果一个子进程是从这三个线中其中一个fork出来的话,那么这个子进程是复制当前这个线程的数据空间和堆栈呢,还是整个这个进程的呢?困惑,谢谢!
[/Quote]

重复一次,完全复制(不考虑写时复制那些具体实现方式),也就是说你fork的时候,父进程里的线程是什么样的,那fork产生的子进程里的线程相对也是完全一样的。

能想通了不?
wlwlwl 2010-03-26
  • 打赏
  • 举报
回复
线程们共享进程的空间,fork就是复制整个进程的空间
冻结 2010-03-26
  • 打赏
  • 举报
回复
apue
龙二伤 2010-03-26
  • 打赏
  • 举报
回复
线程没有独立的运行空间, 而使用进程的用户空间~你说复制什么?
fjx1982441 2010-03-26
  • 打赏
  • 举报
回复
这么做的意义是什么?
geniuschess235 2010-03-26
  • 打赏
  • 举报
回复
fork后的进程使用不同的内存空间。等于新开辟出一块内存空间。
yanran_hill 2010-03-26
  • 打赏
  • 举报
回复
大部分unix系统,在调用fork后,都是复制所有的线程到主进程,不过我记得似乎有一些操作系统(好像是新版的支持posix的solaris记不清了),也支持只复制当前线程,即只复制一个线程,由用户来保证新创建的子进程的线程安全性,如果这时子进程中存在其它线程锁定的mutex等东西,要由用户自己解决资源问题.
mymtom 2010-03-26
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 hairetz 的回复:]

引用楼主 drinker_linux 的回复:
请问fork子进程会是父进程的一个复制品,例如,子进程获得父进程数据空间、堆和栈的复制品。那么请问,如果主进程里有三个线程,这三个线程是分别有自己的堆栈的,如果一个子进程是从这三个线中其中一个fork出来的话,那么这个子进程是复制当前这个线程的数据空间和堆栈呢,还是整个这个进程的呢?困惑,谢谢!


重复一次,完全复制(不考虑写时复制那些具……
[/Quote]


fork后的进程只有一个线程,也就是调用fork的那个线程。

A process is created with a single thread. If a multi-threaded process calls fork(), the new process contains a replica of the calling thread and its entire address space, possibly including the states of mutexes and other resources. Consequently, to avoid errors, the child process may only execute async-signal safe operations until such time as one of the exec functions is called. Fork handlers may be established by means of the pthread_atfork() function in order to maintain application invariants across fork() calls.
独孤过儿 2010-03-26
  • 打赏
  • 举报
回复
关于这个问题的深入分析,手懒就不写了,指点楼主去哪找答案吧

据我所知有两本书里,详细分析了你问的这个问题:

第一本是《UNIX Internals: The new Frontiers》

第二本是 《现代操作系统》(第二版)
jinwei1984 2010-03-26
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 cattycat 的回复:]

fork完全复制父进程的数据和代码。所以和父进程是一样的,另外,线程没有独立的堆栈。
[/Quote]

每个线程有自己的堆栈
kevinyujm 2010-03-26
  • 打赏
  • 举报
回复
进程才有copy,线程共用进程的空间。
规矩就是这样,没什么好想的。
建立楼主结贴。
加载更多回复(2)

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧