文章目录

  • ​​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)创建子进程

  • 函数原型
头文件: unistd.h
pid_t fork(void);

返回值
fork函数被正确调用后,将会在子进程中和父进程中分别返回!!
在子进程中返回值为0(不合法的PID,提示当前运行在子进程中)
在父进程中返回值为子进程ID(让父进程掌握所创建子进程的ID号)
出错返回-1
  • 创建子进程eg
int main(int argc, char **argv)
{
pid_t pid;
pid=fork();
if (pid==-1)
printf("fork error \n");
else if (pid ==0)
{
printf("the returned value is %d\n",pid);
printf("in child process!\n");
printf("My PID is %d\n", getpid());
}
else
{
printf("the returned value is %d\n", pid);
printf("in father process!!\n");
printf("My PID is %d\n",getpid());
}
return 0;
}

(3.8)进程与线程——创建进程_父进程

(3)fork函数的工作流程

  • 创建子进程的操作,实际上就是为子进程分配内核空间资源和用户空间资源的过程
  • 子进程是父进程的副本
    子进程复制/拷贝父进程的PCB、数据空间(数据段、堆和栈)
    父子进程共享正文段(代码段,只读),即:父子进程所执行的代码相同,并且在fork成功返回之后,分别共享相同的代码指针,子进程和父进程继续执行fork函数调用之后的代码,后面else语句啥的…
  • 为了提高效率, fork后不并立即复制父进程数据段、堆和栈,采用了写时复制机制(Copy-On-Write)COW
    当父子进程任意之一要修改数据段、堆、栈时,进行复制操作,并且仅复制修改区域

(4)fork函数执行后,父子进程的主要异同点

(3.8)进程与线程——创建进程_子进程_02

2.父子进程共享文件

(1)父子进程共享打开的文件

(3.8)进程与线程——创建进程_父进程_03

(2)父子进程对共享文件的常见处理方式

  • 父进程等待子进程完成。当子进程终止后,文件当前位置已经得到了相应的更新,父进程才进行文件的操作
  • 父子进程各自执行不同的程序段,各自关闭不需要的文件

3.fork的用法

(1)父进程希望复制自己(共享代码,复制数据空间),但父子进程执行相同代码中的不同分支

  • eg:网络服务程序中,父进程等待客户端的服务请求,当请求达到时,父进程调用fork创建子进程处理该请求,而父进程继续等待下一个服务请求到达

(2)父子进程执行不同的可执行文件(父子进程具有完全不同的代码段和数据空间)

  • eg:子进程从fork返回后,立即调用exec类函数执行另外一个可执行文件

4.vfork函数

  • vfork用于创建新进程,而该新进程的目的是执行另外一个可执行文件,不会与父进程产生任何关联
  • 由于新程序将有自己的地址空间,因此vfork函数并不将父进程的地址空间完全复制到子进程中
  • 子进程在调用exec或exit之前,在父程的地址空间中运行
  • vfork函数保证子进程先执行,在它调用exec或者exit之后,父进程才会继续被调度执行(父进程处于TASK_UNINTERRUPTIBLE状态 (不可响应异步信号的状态),阻塞状态)