一、fork函数
Linux系统中创建进程需要消耗较大资源,所以使用fork函数生成一个子进程,子进程的PCB(进程控制块)会复制父进程的数据!
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char const *argv[])
{
printf("%d\n", getppid());
pid_t p1 = fork();
if(p1 > 0)
{
//父进程
printf("parent pid = %d, p1 = %d\n", getpid(), p1);
}
else
{
//子进程
printf("son pid = %d , ppid = %d, p1 = %d\n", getpid(), getppid(), p1);
}
return 0;
}
这是fork的简单应用,在运行fork()就生成了了一个子进程,父子进程运行的代码是相同的!fork之后的代码在两个进程中运行!
所以fork函数会在父子进程中分别返回,在父进程中返回子进程的pid,而在子进程中会返回0!所以可以根据判断在父子进程中运行不同的代码!
二、僵尸进程和孤儿进程
在进程结束后,Linux系统会自动回收进程消耗的 内存和IO,但是进程本身占用的资源(task_struct和栈内存)不会被回收,需要被父进程来进行回收
(1)僵尸进程
子进程比父进程先结束!
如果父进程没有显示调用wait或waitpid函数的话,会直到父进程结束时才会回收子进程的资源!这样的子进程,就是僵尸进程!
(2)孤儿进程
父进程先于子进程结束,子进程于是成为进程1(init进程)的子进程,直到关机才会回收!
三、wait函数
wait函数原型为 pid_t wait(int *status);
当父进程调用wait时会被阻塞住,直到收到子进程的SIGCHLLD信号,就会回收相关资源!
@return f返回被回收的子进程的pid
@param status 这个地址将会被赋值,可以通过一些宏来判断结束状态!
四、文件读写
当父进程在fork之前打开的文件的文件,文件描述符维护的结构体也被复制,但是父子进程之间的文件描述符对应的文件指针相互关联!
类似不同进程使用O_APPEND打开文件类似!
但是由于父子进程运行速度的原因,可能有一方还没写就被另一方关闭!