vbs结束进程代码_物联⽹学习教程—Linux系统编程之进程控
制
Linux系统编程之进程控制
⼀、结束进程
⾸先,我们回顾⼀下 C 语⾔中 continue, break, return 的作⽤:
continue: 结束本次循环
break: 跳出整个循环,或跳出 switch() 语句
return: 结束当前函数
⽽我们可以通过 exit() 或 _exit() 来结束当前进程。
所需头⽂件:
#include
void exit(int value);
功能:结束调⽤此函数的进程。
参数:
status:返回给⽗进程的参数(低 8 位有效),⾄于这个参数是多少根据需要来填写。
返回值:⽆
所需头⽂件:
#include
void _exit(int value);
功能:结束调⽤此函数的进程。
参数:
status:返回给⽗进程的参数(低 8 位有效),⾄于这个参数是多少根据需要来填写。
返回值:⽆
exit() 和 _exit() 函数功能和⽤法是⼀样的,⽆⾮时所包含的头⽂件不⼀样,还有的区别就是:exit()属于标准库函数,_exit()属于系统调⽤函数。
下⾯的例⼦验证调⽤ exit() 函数,会刷新 I/O 缓冲区
#include
#include
int main(int argc, char *argv[])
{
printf("hi, lh, you are so good"); // 打印,没有换⾏符""
exit(0); // 结束进程,标准库函数,刷新缓冲区,printf()的内容能打印出来// _exit(0); // 结束进程,系统调⽤函数,printf()的内容不会显⽰到屏幕while(1); // 不让程序结束
return 0;
}
运⾏结果:
上⾯的例⼦,结束进程的时候改为调⽤ _exit(),代码如下:
#include
#include
#include
int main(int argc, char *argv[])
{
printf("hi, mike, you are so good"); // 打印,没有换⾏符""
//exit(0); // 结束进程,标准库函数,刷新缓冲区,printf()的内容能打印出来_exit(0); // 结束进程,系统调⽤函数,printf()的内容不会显⽰到屏幕
while(1); // 不让程序结束
return 0;
}
运⾏结果:
接下来,我们⼀起验证⼀下结束函数( return )和结束进程( exit() )的区别。
测试代码如下:
#include
#include
#include
{
sleep(2);
exit(0); // 结束当前进程
while(1);
}
int main(int argc, char *argv[])
{
fun();
printf("after fun");
while(1); // 不让程序结束
return 0;
}
exit() 是可以结束 fun() 所在的进程,即可让程序结束运⾏,结果图如下:
再看如下代码:
#include
#include
#include
void fun()
{vbs基本教程
sleep(2);
return; // 结束 fun() 函数
while(1);
}
int main(int argc, char *argv[])
{
fun();
printf("after fun");
while(1); // 不让程序结束
return 0;
}
通过上⾯的运⾏结果得知,return 的作⽤只是结束调⽤ return 的所在函数,只要这个函数不是主函数( main() ),只要主函数没有结
束,return 并不能结束进程。
⼆、等待进程结束
当⼀个进程正常或异常终⽌时,内核就向其⽗进程发送 SIGCHLD 信号,相当于告诉⽗亲他哪个⼉⼦挂了,⽽⽗进程可以通过 wait() 或waitpid() 函数等待⼦进程结束,获取⼦进程结束时的状态,同时回收他们的资源(相当于,⽗亲听听死去⼉⼦的遗⾔同时好好安葬它)。
wait() 和 waitpid() 函数的功能⼀样,区别在于,wait() 函数会阻塞,waitpid() 可以设置不阻塞,waitpid() 还可以指定等待哪个⼦进程结束
所需头⽂件:
#include
#include
pid_t wait(int *status);
功能:
等待任意⼀个⼦进程结束,如果任意⼀个⼦进程结束了,此函数会回收该⼦进程的资源。
在每个进程退出的时候,内核释放该进程所有的资源、包括打开的⽂件、占⽤的内存等。但是仍然为其保留⼀定的信息,这些信息主要主要指进程控制块的信息(包括进程号、退出状态、运⾏时间等)。
调⽤ wait() 函数的进程会挂起(阻塞),直到它的⼀个⼦进程退出或收到⼀个不能被忽视的信号时才被唤醒(相当于继续往下执⾏)。
若调⽤进程没有⼦进程,该函数⽴即返回;若它的⼦进程已经结束,该函数同样会⽴即返回,并且会回收那个早已结束进程的资源。
所以,wait()函数的主要功能为回收已经结束⼦进程的资源。
参数:
status: 进程退出时的状态信息。
如果参数 status 的值不是 NULL,wait() 就会把⼦进程退出时的状态取出并存⼊其中,这是⼀个整数值(int),指出了⼦进程是正常退出还是被⾮正常结束的。
这个退出信息在⼀个 int 中包含了多个字段,直接使⽤这个值是没有意义的,我们需要⽤宏定义取出其中的每个字段。
下⾯我们来学习⼀下其中最常⽤的两个宏定义,取出⼦进程的退出信息:
WIFEXITED(status)
如果⼦进程是正常终⽌的,取出的字段值⾮零。
WEXITSTATUS(status)
返回⼦进程的退出状态,退出状态保存在 status 变量的 8~16 位。在⽤此宏前应先⽤宏 WIFEXITED 判断⼦进程是否正常退出,正常退出才可以使⽤此宏。
返回值:
成功:已经结束⼦进程的进程号
从本质上讲,系统调⽤ waitpid() 和 wait() 的作⽤是完全相同的,但 waitpid() 多出了两个可由⽤户控制的参数 pid 和 options,从⽽为我们编程提供了另⼀种更灵活的⽅式。
pid_t waitpid(pid_tpid, int *status, intoptions);
功能:等待⼦进程终⽌,如果⼦进程终⽌了,此函数会回收⼦进程的资源。
参数:
pid: 参数 pid 的值有以下⼏种类型:
pid > 0
等待进程 ID 等于 pid 的⼦进程。
pid = 0
等待同⼀个进程组中的任何⼦进程,如果⼦进程已经加⼊了别的进程组,waitpid 不会等待它。
pid = -1
等待任⼀⼦进程,此时 waitpid 和 wait 作⽤⼀样。
pid < -1
等待指定进程组中的任何⼦进程,这个进程组的 ID 等于 pid 的绝对值。
status: 进程退出时的状态信息。和 wait() ⽤法⼀样。
options: options 提供了⼀些额外的选项来控制 waitpid()。
0:
同 wait(),阻塞⽗进程,等待⼦进程退出。
WNOHANG;
没有任何已经结束的⼦进程,则⽴即返回。
WUNTRACED:
如果⼦进程暂停了则此函数马上返回,并且不予以理会⼦进程的结束状态。(由于涉及到⼀些跟踪调试⽅⾯的知识,加之极少⽤到,这⾥就不多费笔墨了,有兴趣的读者可以⾃⾏查阅相关材料)
返回值:
waitpid() 的返回值⽐ wait() 稍微复杂⼀些,⼀共有 3 种情况:
当正常返回的时候,waitpid() 返回收集到的已经⼦进程的进程号;
如果设置了选项 WNOHANG,⽽调⽤中 waitpid() 发现没有已退出的⼦进程可等待,则返回 0;
如果调⽤中出错,则返回 -1,这时 errno 会被设置成相应的值以指⽰错误所在,如:当 pid 所对应的⼦进程不存在,或此进程存在,但不是调⽤进程的⼦进程,waitpid() 就会出错返回,这时 errno 被设置为 ECHILD;
测试代码:
#include
#include
#include
#include
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论