文章目录
- 1.创建进程
- (1)Linux中创建进程的方式
- (3)0号进程和1号进程(init进程)
- (2)创建子进程
- (3)fork函数的工作流程
- (4)fork函数执行后,父子进程的主要异同点
- 2.父子进程共享文件
- 3.fork的用法
- 4.vfork函数
1.创建进程
(1)Linux中创建进程的方式
- 在shell中执行命令或可执行文件
由shell进程调用fork函数创建子进程,并执行输入的命令或可执行文件本身 - 在代码中(已经存在的进程中)调用fork函数创建子进程
通过fork函数创建的进程为已经存在进程的子进程,即:已经存在的进程本身是父进程
(3)0号进程和1号进程(init进程)
- Linux系统中进程0( PID=0)是由内核创建,其他所有进程都是由父进程调用fork函数所创建的
- Linux系统中进程0在创建子进程( PID=1, init进程)后,进程0就转为交换进程或空闲idle进程
- 进程1( init进程)是系统中其他所有进程的共同祖先
(2)创建子进程
- 函数原型
- 创建子进程eg
(3)fork函数的工作流程
- 创建子进程的操作,实际上就是为子进程分配内核空间资源和用户空间资源的过程
- 子进程是父进程的副本
子进程复制/拷贝父进程的PCB、数据空间(数据段、堆和栈)
父子进程共享正文段(代码段,只读),即:父子进程所执行的代码相同,并且在fork成功返回之后,分别共享相同的代码指针,子进程和父进程继续执行fork函数调用之后的代码,后面else语句啥的… - 为了提高效率, fork后不并立即复制父进程数据段、堆和栈,采用了写时复制机制(Copy-On-Write)COW
当父子进程任意之一要修改数据段、堆、栈时,进行复制操作,并且仅复制修改区域
(4)fork函数执行后,父子进程的主要异同点
2.父子进程共享文件
(1)父子进程共享打开的文件
(2)父子进程对共享文件的常见处理方式
- 父进程等待子进程完成。当子进程终止后,文件当前位置已经得到了相应的更新,父进程才进行文件的操作
- 父子进程各自执行不同的程序段,各自关闭不需要的文件
3.fork的用法
(1)父进程希望复制自己(共享代码,复制数据空间),但父子进程执行相同代码中的不同分支
- eg:网络服务程序中,父进程等待客户端的服务请求,当请求达到时,父进程调用fork创建子进程处理该请求,而父进程继续等待下一个服务请求到达
(2)父子进程执行不同的可执行文件(父子进程具有完全不同的代码段和数据空间)
- eg:子进程从fork返回后,立即调用exec类函数执行另外一个可执行文件
4.vfork函数
- vfork用于创建新进程,而该新进程的目的是执行另外一个可执行文件,不会与父进程产生任何关联
- 由于新程序将有自己的地址空间,因此vfork函数并不将父进程的地址空间完全复制到子进程中
- 子进程在调用exec或exit之前,在父程的地址空间中运行
- vfork函数保证子进程先执行,在它调用exec或者exit之后,父进程才会继续被调度执行(父进程处于TASK_UNINTERRUPTIBLE状态 (不可响应异步信号的状态),阻塞状态)