任务描述
在上一关我们学习使用vfork
函数创建新进程,并且使用exit
来结束子进程,本关我们将介绍Linux
系统中结束进程的其它方法。
本关任务:学习终止进程的常见方法。
相关知识
在上一关以及看到,开发人员使用vfork
创建出来的子进程可以用exit
函数来结束。在 Linux
环境中,一个进程的结束,可以通过调用相应的函数实现,也可以是接收到某个信号而结束。
常见与退出进程相关的函数有:exit
、_exit
、atexit
、on_exit
、abort
和assert
。
exit
函数是标准C
库中提供的函数,它用来终止正在运行的程序,并且关闭所有I/O
标准流。_exit
函数也可用于结束一个进程,与exit
函数不同的是,_exit
不会关闭所有I/O
标准流。atexit
函数用于注册一个不带参数也没有返回值的函数以供程序正常退出时被调用。on_exit
函数的作用与atxeit
函数十分类似,不同的是它注册的函数具有参数,退出状态和参数arg
都是传递给该程序使用的。- abort 函数其实是用来发送一个
SIGABRT
信号,这个信号将使当前进程终止。 assert
是一个宏。调用assert
时,它将先计算参数表达式expression
的值,如果为0
,则调用abort
函数结束进程。
[exit
和_exit
区别]
以上关于退出处理函数中只有_exit
是系统调用函数,因此使用man 2 _exit
来查看其使用方法,而其余函数都是库函数,因此使用man 3 函数名
来查看其使用方法。
exit
和_exit
使用方法
exit
函数的具体的说明如下:
- 需要的头文件如下:
#include <stdlib.h>
- 函数族格式如下:
void exit(int status);
status:设置程序退出码;
_exit
函数的具体的说明如下:
-
需要的头文件如下:
#include <unistd.h>
-
函数族格式如下:
void _exit(int status);
参数说明:
status
:设置程序退出码; -
函数返回值说明:
exit
和_exit
均无返回值。
atexit
和on_exit
使用方法
atexit
和on_exit
函数的具体的说明如下:
-
需要的头文件如下:
#include <stdlib.h>
-
函数族格式如下:
int atexit(void (*function)(void));
int on_exit(void (*function)(int , void *), void *arg);
参数说明:
atexit
函数的function
参数是一个函数指针,指向无返回值和无参数的函数;on_exit
函数的function
参数是一个函数指针,指向无返回值和有两个参数的函数,其中第一个参数是调用exit()
或从main
中返回时的值,参数arg
指针会传给参数function
函数; -
函数返回值说明:
atexit
和on_exit
调用成功返回0
;调用失败返回一个非零值。
注意:atexit
和on_exit
只有在程序使用exit
或者main
中正常退出时才会有效。如果程序使用_exit
、abort
或assert
退出程序时,则不会执行被注册的函数。
案例演示1
: 使用atexit
注册一个退出函数,使其在调用退出函数前被执行,详细代码如下所示:
#include <stdlib.h>
#include <stdio.h>
void out()
{
printf("程序正在被退出/n");
}
int main()
{
if(atexit(out) != 0)
{
printf("调用atexit函数错误/n");
}
return 0; //或者exit(0)
}
将以上代码保存为atexit.c
文件,编译执行。可以看到执行atexit
程序后,out
函数被调用。
案例演示2
: 使用on_exit
注册一个退出函数,使其在调用退出函数前被执行,详细代码如下所示:
#include <stdlib.h>
#include <stdio.h>
void out(int status, void *arg)
{
printf("%s(%d)/n", (char *s)arg, status);
}
int main()
{
if(on_exit(out, "程序正在被退出") != 0)
{
printf("调用on_exit函数错误/n");
}
exit(1); //或者return 1
}
将以上代码保存为on_exit.c
文件,编译执行。可以看到执行on_exit
程序后,out
函数被调用,并且status
变量的值就是exit
函数退出的值。
abort
和assert
使用方法
abort
函数的具体的说明如下:
- 需要的头文件如下:
#include <stdlib.h>
- 函数族格式如下:
void abort(void);
assert
宏的具体的说明如下:
- 需要的头文件如下:
#include <assert.h>
- 函数族格式如下:
void assert(scalar expression);
expression
:需要被判断的表达式;
注意:assert
宏通常用于调试程序。
- 函数返回值说明:
abort
和assert
无返回值。
案例演示1: 使用abort
终止一个程序,详细代码如下所示:
#include <stdlib.h>
#include <stdio.h>
int main()
{
printf("Hello world/n");
abort();
}
将以上代码保存为abort.c
文件,编译执行。可以看到执行abort
程序后,程序被强行终止。
编程要求
本关的编程任务是补全右侧代码片段中Begin
至End
中间的代码,具体要求如下:
- 补全
exitProcess
函数,使用atexit
函数注册一个函数,在注册函数中打印出当前进程的ID
号。
测试说明
本关的测试需要用户在右侧代码页中补全代码,然后点击评测按钮,平台会自动验证用户是否按照要求去检测结果。
#include <unistd.h>#include <sys/types.h>#include <stdlib.h>#include <stdio.h>/************************ * 提示: 用户需要在exitProcess函数中使用atexit函数注册一个自定义函数,并在自定义函数中打印出当前进程ID号*************************/void out(){ printf("%d/n",getpid());}void exitProcess(){ /********** BEGIN **********/ if(atexit(out)!=0) { printf("调用atexit函数错误/n"); }}