ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

【进程控制】-2-进程终止

【进程控制】-2-进程终止 ** 博主名称**迷途之人不知返 个人专栏: 《C语言》、《数据结构》、《C》、《Linux》️ Gitee仓库: 《C语言》、《数据结构》、《C》、《Linux》/ 算法专栏: 《算法精选集》进程终止1、概述2、正常退出的情况3、异常退出的情况4、总结5、如何进行进程的正常退出1、概述进程的终止本质上就是操作系统中少了一个进程。进程终止通常有三种情况代码执行完毕计算结果正确代码执行完毕计算结果不正确代码未执行完发生异常。2、正常退出的情况无论计算结果正确与否只要进程的代码执行完毕都算正常退出。以前我们每写一个 C / C 程序最后都要加一个return 0语句那么问题来了return返回的数值到底代表什么呢#includestdio.hintmain(){// ...return0;// 到底代表什么呢}实际上main函数的返回值代表进程的退出码。进程的退出码表示进程执行结果的正确与否。退出码是给父进程看的因为父进程需要知道子进程把任务执行得怎么样。在众多退出码中0表示任务执行成功非0表示失败(运算结果错误)。我们可以借助内置函数strerror将错误码转化为错误信息那么就可以打印看看常见的错误码及对应错误信息#includestdio.h#includestring.hintmain(){inti0;for(;i256;i)printf(%d: %s\n,i,strerror(i));return0;}小贴士1我们可以使用echo $?指令查看最近一个进程退出的退出码。当然echo $?本身的执行也需要创建进程而这个进程一般都是正常结束的。所以连续使用两次echo $?的时候第二次的结果一定是0。3、异常退出的情况进程运行时遇到了某种错误操作系统发现后就发送信号终止进程进程接收信号后就异常退出了。还记得吗一般有这些信号0号信号并没有标明信息是什么因为0号信号代表没有异常。这里有一个有意思的现象是我们对于一个一般的死循环进程发送9号信号可以直接终止进程进程在遇到“除0”操作时也会发生异常系统就会向进程发送8号信号我们就可以给一般的死循环进程发送8号终止信号看看会发生什么至此我们就通过给进程发送8号终止信号模拟出了“除0”错误情况下的进程终止4、总结要衡量一个进程的运行结果是否可靠我们需要观察以下两个数字退出码(exit code)退出信号(signal number)所以我们可以对进程终止的三个结果进行翻译代码执行完毕运算结果正确signal_number 0, exit_code 0代码执行完毕运算结果不正确signal_number 0, exit_code ! 0代码未执行完发生异常signal_number ! 0细节一如果一个进程的退出信号不为0即异常退出那么这个进程的退出码还有意义吗答案是没有。细节二进程的退出码和退出信号保存在哪当然是在进程PCB里头5、如何进行进程的正常退出(异常退出我们就不研究了毕竟谁会想认真研究怎么写BUG)进程的退出一般有两种方法main函数中的return语句调用exit()或_exit()。进程若要通过return语句完成自我的终止就必须在main函数中执行return语句。否则进程在除main的其它任何函数执行return都只是退出当前函数的调用而不是终止进程。这就不太方便。然而exit()在代码的任意地方都能终止进程。进程使用exit()退出退出码正是传入exit()中的参数status。#includestdio.h#includeunistd.h#includestdlib.hintmain(){while(1){printf(Im a process. pid: %d, ppid: %d\n,getpid(),getppid());exit(5);}}当然_exit()也能像exit()一样实现上面的操作。但是exit和_exit亦有区别1、概念的定位不同_exit是下层的系统调用而exit则是上层的库函数。实际上exit也将_exit封装进了exit本身的实现中。2、刷不刷新缓冲区对于_exit我们去掉\n执行看看#includestdio.h#includeunistd.h#includestdlib.hintmain(){while(1){printf(Im a process. pid: %d, ppid: %d,getpid(),getppid());_exit(5);}}打印信息没有出现进程结束的时候exit会冲刷缓冲区而_exit不会冲刷缓冲区。而exit是库函数_exit是系统调用。这就意味着缓冲区一定不是操作系统提供的所以操作系统就对缓冲区不可见。实际上缓冲区在“库”当中。
返回列表