父子进程
Posted DeanBoyLoveLinux
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了父子进程相关的知识,希望对你有一定的参考价值。
fork 后子进程对父进程的继承
(1)为什么需要创建子进程?
每一个程序的运行都需要进程,创建子进程可以实现宏观上的并行
(2)什么时候需要创建子进程?
当父进程执行到某个阶段,或接收到某个事件后,需要创建一个独立的进程来协助其完成任务时,才需要调用fork创建一个新进程
(3)子进程对父进程的继承
1.为什么要继承父进程的相关资源,参考 http://blog.csdn.net/xlsernt_sina_com/article/details/31350829
摘选了两句话:
父进程创建子进程是为了其能够协助父进程完成某些操作,因此,父进程必须将其自己的一些资源分享给子进程,以便父子进程共同完成任务
子进程的创建是为了协助父进程完成相关任务,与此目的不相关的资源,子进程没有必要继承,继承了自会白白浪费内存资源
2.继承的资源, 参考 http://blog.chinaunix.net/uid-24517549-id-4117366.html
- 用户号UIDs和用户组号GIDs
- 环境变量
- 堆栈
- 共享内存
- 打开文件的描述符
- 执行时关闭(Close-on-exec)标志
- 信号(Signal)控制设定
- nice值,该值表示进程的优先级, 数值越小,优先级越高
- 进程调度类别(scheduler class)
- 进程组号
- 对话期ID(Session ID) (指:进程所属的对话期 (session)ID, 一个对话期包括一个或多个进程组, 更详细说明参见《高级编程》 9.5节
- 当前工作目录
- 根目录
- 文件方式创建屏蔽字
- 资源限制
- 控制终端
3.不继承的资源
- 进程号PID
- 不同的父进程号(译者注: 即子进程的父进程号与父进程的父进程号不同, 父进程号可由getppid函数得到)
- 子进程自己的文件描述符和目录流的拷贝
- 异步输入和输出
- 文件锁,pending alarms和pending signals
- timer_create函数创建的计时器
- 阻塞信号集初始化为空集
- 资源使用(resource utilizations)设定为0
- 在tms结构中的系统时间
- 子进程不继承父进程的进程正文(text), 数据和其它锁定内存(memory locks) (译者注:锁定内存指被锁定的虚拟内存页,锁定后, 不允许内核将其在必要时换出(page out), 详细说明参见《The GNU C Library Reference Manual》 2.2版, 1999, 3.4.2节)
4.其他需要注意的
1.父进程和子进程拥有独立的地址空间和PID参数
2.经过fork()以后,父进程和子进程拥有相同内容的代码段、数据段和用户堆栈(共享内存)
3.就像父进程把自己克隆了一遍。事实上,父进程只复制了自己的PCB块。而代码段,数据段和用户堆栈内存空间并没有复制一份,而是与子进程共享。只有当子进程在运行中出现写操作时,才会产生中断,并为子进程分配内存空间。由于父进程的PCB和子进程的一样,所以在PCB中断中所记录的父进程占有的资源,也是与子进程共享使用的。这里的“共享”一词意味着“竞争”
(4)fork的返回值
fork函数调用一次会返回2次,首先返回pid = 0,返回值等于0的就是子进程;再返回pid 大于0,返回值大于0的是父进程,且这个返回值就是本次 fork创建的子进程ID
(5)父进程对子进程的回收
1.孤儿进程:父进程先结束的时候,系统会把init进程(进程1)变为子进程的父进程
2.僵尸进程:子进程先于父进程结束,父进程还未来得及将其收尸(系统只是回收了这个进程工作时消耗的内存和IO,而并没有回收这个进程本身占用的内存,8KB,主要是task_struct和栈内存))
3.回收函数
wait:阻塞,子进程结束时,系统向其父进程发送SIGCHILD信号 pid_t wait(int *status);
参考 http://blog.csdn.net/qq_18973645/article/details/52648812
waitpid:可以回收指定PID的子进程,可以阻塞式或非阻塞式两种工作模式
pid_t waitpid(pid, &status, 0); //0默认表示阻塞
pid_t waitpid(pid,&status,WNOHANG) //表示非阻塞
以上是关于父子进程的主要内容,如果未能解决你的问题,请参考以下文章