宁波手机网站制作,官方网站作用,大学生网站开发目的,电子商城网站开发合同文章目录 1.进程等待1.1进程等待必要性1.1.1为什么有进程等待这个概念1.1.2进程等待是什么#xff1f;1.1.3进程等待具体干什么#xff1f; 1.2进程退出方法#xff1a; 2.具体代码实现 1.进程等待
1.1进程等待必要性
1.1.1为什么有进程等待这个概念
之前讲过#xff0c… 文章目录 1.进程等待1.1进程等待必要性1.1.1为什么有进程等待这个概念1.1.2进程等待是什么1.1.3进程等待具体干什么 1.2进程退出方法 2.具体代码实现 1.进程等待
1.1进程等待必要性
1.1.1为什么有进程等待这个概念
之前讲过子进程退出如果父进程不管不问那么就可能会造成僵尸进程的问题僵尸进程杀不死本节所讲的进程等待就是杀掉僵尸进程的方法从而解决因为僵尸进程而导致的内存泄漏问题。我们要通过进程等待来获取子进程的退出情况即知道父进程我布置给子进程的任务完成的怎么样了要么关心也可能不关心通过设置选项可以选择关心与否。
1.1.2进程等待是什么
通过系统调用wait/waitpid来进行对进程运行状态进行检测与回收功能。
1.1.3进程等待具体干什么
通过代码实现:父进程通过调用wait/waitpid进行僵尸进程的回收问题!
1.2进程退出方法
wait方法
#includesys/types.h
#includesys/wait.h
pid_t wait(int*status);
返回值
成功返回被等待进程pid失败返回-1。
参数
输出型参数获取子进程退出状态,不关心则可以设置成为NULL例如如下代码
#includestdio.h2 #includesys/types.h3 #includesys/wait.h4 #include stdlib.h5 #include unistd.h6 int main()7 {8 pid_t id fork();9 if(id 0)10 {11 printf(I am a Child Process,pid:%d,ppid:%d\n,getpid(),getppid());12 exit(1);13 } 14 else if(id 0) 15 { 16 perror(fork);17 return 1;18 }19 else20 {21 while(1)22 {23 pid_t ret wait(NULL);24 if(ret 0) 25 {26 printf(wait failed\n);27 break;28 }29 else if(ret 0)30 {31 printf(进程是正常跑完的, 退出码:%d\n,ret);32 break;33 }34 else{35 printf(进程还结束请等待哦\n);36 break;37 }38 }39 }运行结果为 waitpid方法 pid_ t waitpid(pid_t pid, int *status, int options); 返回值 当正常返回的时候waitpid返回收集到的子进程的进程ID 如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0 如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在 参数
pidPid-1,等待任一个子进程。与wait等效。Pid0.等待其进程ID与pid相等的子进程。status:WIFEXITED(status): 若为正常终止子进程返回的状态则为真。查看进程是否是正常退出 WEXITSTATUS(status): 若WIFEXITED非零提取子进程退出码。查看进程的退出码options: WNOHANG: 若pid指定的子进程没有结束则waitpid()函数返回0不予以等待。若正常结束则返回该子进程的ID。
1.如果子进程已经退出调用wait/waitpid时wait/waitpid会立即返回
并且释放资源获得子进程退出信息。
2.如果在任意时刻调用wait/waitpid子进程存在且正常运行则进程可能阻塞。
3.如果不存在该子进程则立即出错返回。代码如下
#includestdio.h2 #include stdlib.h3 #include unistd.h4 #include sys/types.h5 #include sys/wait.h6 7 #define N 108 void RunChild()9 {10 int cnt 5;11 while(cnt)12 {13 printf(I am Child Process, pid: %d, ppid:%d\n, getpid(), getppid());14 sleep(1);15 cnt--;16 }17 }18 int main()19 {20 /*for(int i0;iN;i)21 {22 pid_t id fork();23 if(id 0)24 { 25 RunChild();26 exit(i);27 }28 printf(Creat Child Process: %d Success\n,id);29 }30 return 0;*/31 pid_t id fork();32 if(id 0)33 {34 perror(fork);35 return 1;36 }37 else if (id 0)38 {39 int cnt 5;40 while(cnt)41 {42 printf(I am child,pid:%d,ppid:%d,cnt:%d\n,getpid(),getppid(),cnt);43 cnt--;44 sleep(1);45 }46 exit(11);47 }48 else{49 /* int cnt 5;50 while(cnt)51 {52 printf(I am father, pid:%d, ppid:%d, cnt: %d\n, getpid(), getppid(), cnt);53 cnt--;54 sleep(1);55 }*/ 56 int status 0;57 while(1) 58 {59 pid_t ret waitpid(id, status, WNOHANG); //非阻塞60 if(ret 0)61 {62 if(WIFEXITED(status))63 {64 printf(进程是正常跑完的退出码为%d\n,WEXITSTATUS(status));65 }66 else 67 {68 printf(进程异常退出了。\n);69 }} 70 break;71 }72 else if(ret 0)73 {74 printf(wait failed\n);75 break;76 }77 else{78 printf(你好了没子进程还没有退出我在等等...\n);79 sleep(1);80 81 }82 83 }84 }85 return 0;86 } 获取子进程status
wait和waitpid都有一个status参数该参数是一个输出型参数由操作系统填充。如果传递NULL表示不关心子进程的退出状态信息。否则操作系统会根据该参数将子进程的退出信息反馈给父进程。status不能简单的当作整形来看待可以当作位图来看待具体细节如下图只研究status低16比特位 测试代码如下
#include sys/wait.h
#include stdio.h
#include stdlib.h
#include string.h
#include errno.h
int main( void )
{pid_t pid;if ( (pidfork()) -1 )perror(fork),exit(1);if ( pid 0 ){sleep(20);exit(10);} else {int st;int ret wait(st);if ( ret 0 ( st 0X7F ) 0 ){ // 正常退出printf(child exit code:%d\n, (st8)0XFF);} else if( ret 0 ) { // 异常退出printf(sig code : %d\n, st0X7F );}}
}测试结果为
2.具体代码实现
进程的阻塞等待方式
int main()
{pid_t pid;pid fork();if(pid 0){printf(%s fork error\n,__FUNCTION__);//__FUNCTION__: 这是一个预编译器内置宏它会被替换为当前函数的名称。//所以如果你在函数my_function中调用了这条语句__FUNCTION__会被替换为my_function。如果fork函数出错通常fork的返回值是-1表示出错则打印出“函数名 fork error”并换行。return 1;} else if( pid 0 ){ //childprintf(child is run, pid is : %d\n,getpid());sleep(5);exit(257);} else{int status 0;pid_t ret waitpid(-1, status, 0);//阻塞式等待等待5Sprintf(this is test for wait\n);if( WIFEXITED(status) ret pid ){printf(wait child 5s success, child return code is:%d.\n,WEXITSTATUS(status));}else{printf(wait child failed, return.\n);return 1;}}return 0;
}
进程的非阻塞等待方式
#include stdio.h
#include unistd.h
#include stdlib.h
#include sys/wait.h
int main()
{pid_t pid;pid fork();if(pid 0){printf(%s fork error\n,__FUNCTION__);return 1;}else if( pid 0 ){ //childprintf(child is run, pid is : %d\n,getpid());sleep(5);exit(1);} else{int status 0;pid_t ret 0;do{ret waitpid(-1, status, WNOHANG);//非阻塞式等待if( ret 0 ){printf(child is running\n);}sleep(1);}while(ret 0);if( WIFEXITED(status) ret pid ){printf(wait child 5s success, child return code is :%d.\n,WEXITSTATUS(status));}else{printf(wait child failed, return.\n);return 1;}}return 0;
}