进程退出,等待

进程的退出(_exit,exit,return)

exit和_exit:两者都可以在任意位置,退出进程,并且返回退出码
区别:exit是C语言库函数其不仅仅会进行程序退出,还会进行某些资源的的清理,如刷新缓冲区_exit是系统调用就只是进程退出,不会做资源的清理
示例代码:下面就不会打印出本该打印的字符串,原因就是直接被进程直接退出,且没有清理后续资源,那部分资源也就被清理掉了。
//由此可以看见,缓冲区不在系统层面,否则来自系统层面的_exit是可以进行清理的。

  1 #include <stdio.h>                                                                                                                                                                                                                     
  2 #include <stdlib.h>
  3 #include <unistd.h>
 19 int main()
 20 {
 21 
 23     printf("pid is %d,ppid is%d    ---",getpid(),getppid());
 		sleep(2);
 23     _exit(101);
 24     //exit(100);//换成exit即可看见打印内容
 25     return 32;//you can see the exit code by the "echo $? following the process exited"
 26 }

进程的等待

为什么要有:
1.处理子进程的僵尸状态—这是必须的
2.获取子进程退出信息,以了解子进程的完成情况

wait,waitpid:两个都用于进程等待
下面是通过man查看的手册。
在这里插入图片描述
参数就是首先不同,wait作用是等待任意一个进程,等到就返回,且是阻塞形等待。
两者都有**status:**下面会详细介绍,其真正的作用(通过整形指针给整形赋值)是得到返回信息,所以如果你传空指针,意味着就不在意子进程的返回情况。
pid:
可以通过给pid传参数,选择等待任意一个进程,如果传值给-1,其就表示可以等待任意一个进程,option再传0的话,和wait效果就一样了。
**options:**传0或者1(默认的是0,也就是阻塞等待)来选择等待的类型,轮询等待还是阻塞形式等待
返回值意思也是同样的,成功返回等到的子进程的pid,失败的话返回小于0的数。

status

**statu的构成:一个32位的整数,但实际传过去用的时候,只用了低16位的数字而不是全用。 **
在这低16位的使用之中:

高八位是用于表示退出码
低7位表示的是退出信号(表示代码执行情况)
WTERMSIG(status) 可以获取低7位的信号码
WEXITSTATUS 获取退出码·

上面我们就能看见,这是一个整形指针。

    1 #include <stdio.h>
    2 #include <stdlib.h>
    3 #include <unistd.h>
    4 #include <sys/wait.h>
    5 #include <sys/types.h>
    6 
    7 void Worker()
    8 {
    9     for(int cnt = 0;cnt<5;cnt++)
   10     {
   11         //int a = 1;                                                                                           
W> 12         //a/=0;//测试信号码
   13         printf(" child process,pid is %d ,ppid is %d \n",getpid(),getppid());
   14         sleep(1);
   15     }
   16 }
   17 int main()
   18 {
   19     pid_t pid = fork();
   20     if(pid==0)
   21     {
   22         //child process
   23         Worker();
   24         exit(0);
   25     }
   26     else{
   27         sleep(10);
   28        // pid_t rid = wait(NULL);
   29        int status = 0;
   30        pid_t rid = waitpid(pid,&status,0);
   31        printf("%d",status);
   32         if(rid == pid)
   33         {
   34             printf("wait success ,pid : %d,exitsig:%d,exit code:%d",getpid(),status&0x7F,(status>>8)&0xFF);
   35         }
   36     }
   37     return 0;
   38 }

上面注释部分如果取消,下面就可以是答案,我们通过这点可以发现,信号码出现错误了,退出码其实就没什么价值了
子进程被杀掉,也算是异常(按我们日常使用的理解,突然关闭某个程序,确实应该就算异常)
在这里插入图片描述

阻塞形等待:下面就是示例,在等待的时候,父进程会挂起等着子进程结束。
下面代码运行时,可以查看进程状况,即可发现,子进程的僵尸进程就被处理了。

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 #include <sys/wait.h>
  5 #include <sys/types.h>
  6 
  7 void Worker()
  8 {
  9     for(int cnt = 0;cnt<5;cnt++)
 10     {
 11         printf(" child process,pid is %d ,ppid is %d \n",getpid(),getppid());
 12         sleep(1);
 13     }
 14 }
 15 int main()
 16 {
 17     pid_t pid = fork();
 18     if(pid==0)
 19     {
 20         //child process
 21         Worker();
 22         exit(0);
 23     }
 24     else{
 25         sleep(10);
 26         pid_t rid = wait(NULL);//NULL表示不在乎子进程进行情况
 27         if(rid == pid)                                                       
 28         {
 29             printf("wait success ,pid : %d\n",getpid());
 30         }
 31     }
 32     return 0;
 33 }

在这里插入图片描述

//下面是创建了十个子进程,用waitpid去回收。
从其结果来说,说明进程的执行情况是各不相同的,子进程先创建,不会就先执行完,其调度不是认为创建先后就决定的。

    1 #include <stdio.h>
    2 #include <stdlib.h>
    3 #include <unistd.h>
    4 #include <sys/wait.h>
    5 #include <sys/types.h>
    6 
W>  7 void Worker(int i)
    8 {
    9     for(int i = 0;i<2;i++)
   10     {
   11         printf("I am a child process,pid is %d,ppid is %d\n",getpid(),getppid());
   12         sleep(1);
   13     }
   14 }
   15 
   16 int main()
   17 {
   18     for(int i = 0;i<10;i++)
   19     {
   20         pid_t id = fork();
   21         if(id==0)
   22         {
   23             //child
   24             Worker(i);
   25             exit(i);
   26         }
   27     }
   28     for(int i = 0;i<10;i++)
   29     {
   30         int status;
   31         pid_t rid = waitpid(-1,&status,0);//pid is always larger than 1, -1 is the wait child pr      ocess can be anyone
   32         if(rid>0)
   33         {
   34             printf("child process id:: %d<< success\n",status>>8);                              
   35         }
   36     }
   37 
   38     return 0;
   39 }


在这里插入图片描述

轮询式等待

  1 #include <stdio.h>                                                                                                                                                                                                                          
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 #include <sys/wait.h>
  5 #include <sys/types.h>
  6 
  7 #define TASK_NUM 2
  8 
  9 typedef void(*tskPtr)();
 10 
 12 void download()
 13 {
 14     printf("this is a download\n");
 15 }
 16 
 17 void show()
 18 {
 19     printf("this is a show info \n");
 20 }
 21 
 22 void InitialTasks(tskPtr task[],int num)
 23 {
 24     for(int i = 0;i<num;i++) task[i] = NULL;
 25 }
 26 
 27 int AddTask(tskPtr task[],tskPtr t)
 28 {
 29     for(int i= 0;i<TASK_NUM;i++)
 30     {
 31         if(task[i]==NULL)
 32         {
 33             task[i] = t;
 34             return 1;
 35         }
 36     }
 37     return 1;
 38 }
 39 
 40 void executeTask(tskPtr task[],int num)
 41 {
 42     for(int i = 0;i<num;i++)
 43     {
 44         task[i]();
 45     }
 46 }
 47 
 48 int main()
 49 {
 50     tskPtr task[TASK_NUM];
 51     InitialTasks(task,TASK_NUM);
 52     AddTask(task,download);
 53     AddTask(task,show);
 54     
 55     pid_t pid = fork();                                                                                                                                                                                                                     
 56     if(pid==0)
 57     {
 58        int cnt=10;

59        while(--cnt)
 60        {
 61             sleep(1);
 62             printf("I am child process ,pid is %d,time left is %d\n",getpid(),cnt);
 63        }
 64 
 65             exit(0);
 66     }
 67     else{
 68         //father
 69         pid_t rid;
 70         while(1)
 71         {
 72             int status = 0;
 73             rid = waitpid(pid,&status,1);
 74             if(rid>0)
 75             {
 76                 sleep(1);
 77                 printf("child process success,exit code: %d,exit signal:%d\n",(status>>8)&0xFF,status&0x7F);
 78                 break;
 79             }
 80             else if(rid==0)
 81             {
 82                 sleep(1);
 83                 executeTask(task,TASK_NUM);
 84                 printf("wait child proceess ,father can do others\n");
 85             }
 86             else{
 87                 sleep(1);
 88                 printf("wait flase,rid id%d\n",rid);
 89                 break;
 90             }
 91         }
 92     }
 93     return 0;
 94 }         

在这里插入图片描述
观察可得,这种等待期间,是可以去父进程可以执行其他时间,只需要每隔一段时间来等待子进程就可以,而不是直接挂起等着子进程,同时子进程也可以执行一些任务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值