do_exit函数功能描述:此函数结束当前正在执行的线程,释放占用的CPU资源。
do_exit文件包含
#include <linux/kernel.h>
do_exit函数定义
在内核源码中的位置:linux-3.19.3/kernel/exit.c
函数定义格式:
void do_exit(long error_code) __noreturn;
do_exit输入参数说明
参数error_code是long型变量,是进程的退出码,是子进程返回给父进程的值。
do_exit返回参数说明
此函数的返回值是void型变量,即不返回任何值。__noreturn其作用是声明如果某函数调用了函数do_exit( ),而此函数在正常情况下是有返回值的,此时不会返回任何值,程序不会报告错误。
do_exit实例解析
编写测试文件:do_exit.c
头文件引用:
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/pid.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
MODULE_LICENSE("GPL");
子进程执行函数定义:
int my_function(void * argc)
{
//do_exit(0); //退出线程
printk("in the kernel thread function! \n");
printk("the current pid is:%d\n", current->pid); //显示当前进程的PID号
printk("out the kernel thread function\n");
return 0;
}
模块加载函数定义:
static int __init do_exit_init(void)
{
struct task_struct * result;
char namefrm[] = "do_exit";
printk("into do_exit_init.\n");
result=kthread_create_on_node(my_function, NULL, -1, namefrm); //创建子线程
wake_up_process(result);
struct pid * kpid=find_get_pid(result->pid); //获取其新进程的描述符信息
/*显示新进程的PID号*/
printk("the pid of the find_get_pid is :%d\n", kpid->numbers[kpid->level].nr);
/*显示函数kthread_create_on_node( )函数的调用结果*/
printk("the pid of new thread is :%d\n", result->pid);
printk("out do_exit_init.\n");
return 0;
}
模块退出函数定义:
static void __exit do_exit_exit(void)
{
printk("Goodbye do_exit\n");
}
模块加载、退出函数调用:
module_init(do_exit_init);
module_exit(do_exit_exit);
实例运行结果及分析:
首先编译模块,执行命令insmod do_exit.ko插入模块,然后执行命令dmesg -c,会出现如图A
所示的结果。
然后卸载模块,更改源文件,注释掉语句“do_exit( ); ”,重新编译文件,再次执行命令insmod do_exit.ko插入内核模块,输入命令dmesg -c查看内核输出信息,出现如图B
所示结果。
结果分析:
图A
中可以看出子进程创建成功,但子进程没有输出任何结果,而图B
中子进程的输出结果成功显示,通过对比两图可以看出在包含语句“do_exit( )”时,执行到子进程处理函数,do_exit( )函数使子进程成功退出,从而说明了函数do_exit( )能够成功结束当前正在执行的进程。