linux系统编程之进程(四)
今天继续研究进程相关的东东,话不多说,进入正题:
#include <unistd.h> #include <sys/stat.h> #include <sys/wait.h>//提供wait函数声明 #include <sys/types.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <signal.h> #define ERR_EXIT(m) do { perror(m); exit(EXIT_FAILURE); } while(0) int main(int argc, char *argv[]) { pid_t pid; pid = fork(); if (pid == -1) ERR_EXIT("fork error"); if (pid == 0) { sleep(3);//子进程休眠,是为了看到父进程会等待子进程退出 printf("this is child\n"); exit(100); } printf("this is parent\n"); int status; wait(&status);等待子进程退出 return 0; }
看一下编译运行效果,下面用动画来展现,以便能体现到wait的意义:
从图中可以感受到,父进程虽然是已经输出了,但是一直是等到子进程退出了才退出,这也就是wait会让父进程去查子进程的退出状态,从而避免了僵尸进程的出现。
编译运行:
对于这些状态信息,可以通过调用系统宏来查询,下面具体来介绍下:
用来代码来解释:
编译运行:
下面我们可以用abort函数,来模拟子进程非法退出的情况:
这时再编译运行:
实际上,对于子进程非法退出的,还可以判断得再仔细一些,因为有好几种情况可以造成子进程非法退出,如上图所示,一是因为捕获信号而终止,二是被暂停了,具体用法如下:
编译运行:
关于信号,由于还没有学到,所以暂停的信号就不多说了,这里就不演示暂停信号的情况了,重在理解一下获取子进程退出状态信息的用法。
【说明:上面的这些宏在sys/wait.h头文件里定义】
#include <unistd.h> #include <sys/stat.h> #include <sys/wait.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <signal.h> #define ERR_EXIT(m) do { perror(m); exit(EXIT_FAILURE); } while(0) int my_system(const char *command);//自己实现有system函数声明 int main(int argc, char *argv[]) { my_system("ls -l | wc -w");//这里改用自己实现在system return 0; } int my_system(const char *command) { pid_t pid; int status; if (command == NULL) return 1;
if ((pid = fork()) < 0) status = -1;//出现不能执行system调用的其他错误时返回-1
else if (pid == 0) {//子进程 execl("/bin/sh", "sh", "-c", command, NULL);//替换成sh进程 exit(127);//如果无法启动shell运行命令,system将返回127,因为如果成功替换了之后,是不会执行到这句来的
} else {//父进程会等到子进程执行完 while (waitpid(pid, &status, 0) < 0) { if (errno == EINTR)//如果是被信号打断的,则重新waitpid continue; status = -1; break; }
//这时就顺利执行完了 } return status; }
编译运行:
可见,通过自己实现的system,就能够大致弄清楚它的原理,虽说程序比较少,但是五脏俱全,因为可以把自己学过的知识给运用起来。
好了,今天的学习就到这,下次见。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。