wake_up_process函数功能描述:此函数用于唤醒处于睡眠状态的进程,使进程由睡眠状态变为RUNNING状态,从而能够被CPU重新调度执行。
wake_up_process文件包含
#include <linux/sched.h>
wake_up_process函数定义
在内核源码中的位置:linux-3.19.3/kernel/sched/core.c
函数定义格式:
int wake_up_process(struct task_struct *tsk)
wake_up_process输入参数说明
此函数的输入参数为进程的描述符信息,保存进程的一些基本信息,此结构体的定义见文件linux-3.19.3/include/linux/sched.h,内核注释比较详细。
wake_up_process返回参数说明
此函数的返回结果是int型的变量,代表唤醒进程的情况,可能的取值是0或1。返回1代表当前进程不是处于RUNNING状态,唤醒进程成功;返回0代表当前进程处于RUNNING状态或唤醒进程失败。
wake_up_process实例解析
编写测试文件:wake_up_process.c
头文件引用及全局变量定义:
/*头文件引用*/
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/pid.h>
#include <linux/wait.h>
#include <linux/list.h>
#include <linux/kthread.h>
#include <linux/delay.h>
MODULE_LICENSE("GPL");
/*全局变量定义*/
struct task_struct * old_thread; //保存进程描述符信息
子进程处理函数定义:
int my_function(void * argc)
{
int data=-1; //保存wake_up_process( )返回结果
printk("in the kernel thread function! \n");
printk("the current pid is:%d\n", current->pid); //显示当前进程的PID值
/*显示父进程的状态*/
printk("the state of the init function is :%ld\n", old_thread->state);
data=wake_up_process(old_thread); //唤醒模块初始化函数
// 显示函数调用之后的父进程的状态
printk("the state of the init function after wake_up_process is :%ld\n", old_thread->state);
printk("the result of the wake_up_process is:%d\n", data);
printk("out the kernel thread function\n");
return 0;
}
C
模块加载函数定义:
static int __init wake_up_process_init(void)
{
char namefrm[]="wake_up_process.c%s"; //线程的输出类型名,在此程序中无影响
int result_data=-1; //保存wake_up_process( )结果
long time_out;
struct task_struct * result;
wait_queue_head_t head; //等待队列头元素
wait_queue_t data; //等待队列元素
printk("into wake_up_process_init.\n");
result=kthread_create_on_node(my_function, NULL, -1, namefrm); //创建新进程
printk("the pid of the new thread is:%d\n", result->pid); //显示新线程的PID值
printk("the current pid is:%d\n", current->pid); //显示当前进程的PID值
init_waitqueue_head(&head); //初始化等待队列头元素
init_waitqueue_entry(&data, current); //用当前进程初始化等待队列中的一个元素
add_wait_queue(&head, &data); //将等待队列元素加入等待队列中
old_thread=current; //记录当前进程的信息
result_data=wake_up_process(result); //唤醒新创建的线程
printk("the result of wake_up_process for new thread is: %d\n", result_data);
time_out=schedule_timeout_uninterruptible(1000*10); //让当前进程进入睡眠状态
result_data=wake_up_process(current); //唤醒当前进程,当前进程处于RUNNING状态
printk("the result of wake_up_process for init thread is: %d\n", result_data);
//输出schedule_timeout_uninterruptible( )返回结果
printk("the schedule timeout is:%ld\n", time_out);
printk("out wake_up_process_init.\n");
return 0;
}
模块退出函数定义:
static void __exit wake_up_process_exit(void)
{
printk("Goodbye wake_up_process\n");
}
模块加载、退出函数调用:
module_init(wake_up_process_init);
module_exit(wake_up_process_exit);
实例运行结果及分析:
首先编译模块,执行命令insmod wake_up_process.ko插入模块,然后输入命令dmesg -c,会出现如图所示的结果。
结果分析:
由图可以看出在模块初始进程运行的过程中,新进程被调度执行了,此时模块初始进程的状态输出值是2,说明模块初始进程处于TASK_UNINTERRUPTIBLE状态,此状态的定义值是2。当函数wake_up_process( )调用之后,模块初始进程的状态值变为了0,说明模块初始进程处于RUNNING状态,此状态的定义值是0。由上图可以看出模块初始进程中调用函数wake_up_process( )唤醒新进程的返回值是1及在新进程中调用wake_up_process( )函数唤醒模块初始进程的返回值也是1,说明唤醒进程成功,因为调用函数wake_up_process( )时,两个进程处于非RUNNING状态。在模块初始进程中再次的调用函数wake_up_process( )唤醒模块初始进程的返回值是0,说明唤醒进程失败,因为此时模块初始进程已处于RUNNING状态。
进程状态说明:
对于进程能够处于的状态,在函数__wake_up( )的进程状态说明部分有详细的说明。