1.vfork创建进程
vfork函数 也可以创建进程,与fork有什么区别
关键区别一:
vfork直接使用父进程存储空间,不拷贝。
关键区别二:
vfork保证子进程先运行,当子进程调用exit退出后,父进程才执行。
如果使用fork调用 while(1)死循环 让父子进程一直争夺cpu资源 有可能一人一次 也有可能是一个人一直争到
vforktest9.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t pid;
int cnt = 0;
pid = vfork();
if(pid > 0){
while(1){
printf("this is father print,father pid = %d\n",getpid());
sleep(1);
printf("cnt=%d\n",cnt);
}
}
else if(pid == 0){
while(1){
printf("this is child print,child pid = %d\n",getpid());
sleep(1);
cnt++;
if(cnt == 3)
{
exit(0);
}
}
}
return 0;
}
运行结果为: exit(1)是直接退出整个程序, exit(0)退出当前循环
2.进程退出
正常退出
1.Main函数调用return
2.进程调用exit,标准C库
3。进程调用_exit()或者_Exit(),属于系统调用
补充:
1.进程最后一个线程返回
2.最后一个线程调用pthread_exit
异常退出
1.调用abort
2.当进程收到某些信号时,如ctrl+C
3.最后一个线程对取消(cancellation)请求做出响应
status是状态码
3.父进程等待子进程的退出(一)僵尸进程
为什么要等待子进程的退出?
收集退出状态
创建子进程目的——>干活 干完 ——>exit(状态码) 状态码:0 1 2
没干完 ——> abort
——>杀死
{
{ 正常: 5种
{ 异常: 3种
{
父进程等待子进程退出并手机子进程的退出状态
子进程退出状态不被收集,变成僵死进程(僵尸进程)
如果没有在pid>0(父进程内 让父进程先等待)内调用wait 子进程就会变成僵尸
扫描二维码关注公众号,回复:
13135437 查看本文章
![](/qrcode.jpg)
S+代表着进程正在运行 而Z+代表着 zombie 意思是僵尸的意思
区别:wait使调用者阻塞,waitpid有一个选项,可以使调用者不阻塞
status参数:是一个整型数指针
非空:子进程退出状态放在它所指向的地址种。
空(NULL):不关心推出状态
waittest13.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main()
{
pid_t pid;
int cnt = 0;
int status = 10;
pid = fork();
if(pid > 0)
{
wait(&status); //让父进程先等待 防止子进程变成僵尸
printf("child quit,child status = %d\n",WEXITSTATUS(status));
while(1){
printf("this is father print,father pid = %d\n",getpid());
sleep(1);
printf("cnt=%d\n",cnt);
}
}
else if(pid == 0){
while(1){
printf("this is child print,child pid = %d\n",getpid());
sleep(1);
cnt++;
if(cnt == 5)
{
exit(3);
}
}
}
return 0;
}
运行结果为:
int status = 10;
wait(&status);
printf("child quit,child status = %d\n",WEXITSTATUS(status));
//来获取子进程退出状态码
4.父进程等待子进程的退出(二)孤儿进程
1.如果其所有子进程都还在运行,则阻塞。
2.如果一个子进程已终止,正等待父进程获取其终止状态,则取得该子进程的终止状态立即返回。
3.如果它没有任何子进程,则立即出错返回。
孤儿进程
父进程如果不等待子进程退出,在子进程之前就结束了自己的“生命”,此时子进程叫做孤儿进程
Linux 避免系统存在过多孤儿进程,init进程收留孤儿进程,变成孤儿进程的父进程
guertest15.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main()
{
pid_t pid;
int cnt = 0;
int status = 10;
pid = fork();
if(pid > 0)
{
printf("this is father print,father pid = %d\n",getpid());
}
else if(pid == 0){
while(1){
printf("this is child print,child pid = %d,my father pid = %d\n",getpid(),getppid());
sleep(1);
cnt++;
if(cnt == 5)
{
exit(3);
}
}
}
return 0;
}
father pid = 1724 属于init的pid ,是init进程收留孤儿进程