进程的组成:
text | data | bss | 堆 栈 | 系统数据|
1.进程的诞生
[1].fork() // fork 叉子
注:
fork创建子进程的过程
[1].通过复制调用fork的进程 来实现新进程的创建
新进程是调用进程的复制品
新进程被称为 "子进程"
原先的调用进程 称为 "父进程"
[2].复制了哪些东西?
a.原先进程中有哪些东西?
|text | data | bss | 堆 栈 | 系统数据|
复制之后:
新的进程获得了一份原先进程的组成的各个部分
|text | data | bss | 堆 栈 | 系统数据|
b.梳理:
代码段 和 数据段
c.拷贝了一些寄存器的值
pc (Program Counter) //指向下一条要执行的指令
#include <stdio.h>
#include <unistd.h>#include <stdlib.h>
int main(int argc, const char *argv[])
{
pid_t pid;
int status = 0; //没有初始化时 ,status为随机值
pid =fork();//创建子进程 --- pc 程序计数器
// 创建子进程时,子进程也拷贝了父进程的pc值
// 指向了fork之后的下一条语句
// 此处 fork 之后的下一句为
// 赋值语句
// 将:fork的返回值赋值给pid变量
if(pid < 0)//如果pid小与0表示创建子进程失败
{perror("fork fail");
exit(EXIT_FAILURE);
}
if(pid > 0) //父进程
{
while(1)
{
printf("father pid = %d\n",getpid());
sleep(1);
//wait(&status); //收尸 ---回收资源的同时,可以接收子进程的退出状态值
waitpid(-1,&status,WNOHANG|WUNTRACED|WCONTINUED);
if(WIFEXITED(status))
printf("status = %d\n",WEXITSTATUS(status));
if(WIFSIGNALED(status)) //如果子进程是被信号结束了 ,则为真
printf("signal status = %d\n",WTERMSIG(status));
//R->T
if(WIFSTOPPED(status))
printf("stop sig num = %d\n",WSTOPSIG(status));
//T->R
if(WIFCONTINUED(status))
printf("continue......\n");
}
}else if(pid == 0)//子进程
{
while(1)
{
printf("child exit...\n");
sleep(1);
// exit(89); //退出时 给父进程 返回一个 退出状态值
}
}
return 0;
}
注意:
父进程中的wait()阻塞方法它会等待子进程执行完,帮子进程进行收尸处理(如释放它所占用的资源)并且它只能处理一个子线程为了处理所有子线程可以把wait放在while中
还有时创建的进程会接着fork语句后面执行