__wake_up_sync_key函数功能描述:此函数用于唤醒等待队列中处于特定状态的进程,此特定状态由第二个参数mode给出。当进程的状态满足此特定状态时就有可能被唤醒,获得CPU资源,从而被调度执行。此函数唤醒的进程不会改变进程之前所在的CPU,不会引起额外的CPU的抢占,并且可以同步唤醒进程。
__wake_up_sync_key文件包含
#include <linux/wait.h>
__wake_up_sync_key函数定义
在内核源码中的位置:linux-3.19.3/kernel/sched/wait.c
函数定义格式:
void __wake_up_sync_key(wait_queue_head_t *q, unsigned int mode, int nr, void * key)
__wake_up_sync_key输入参数说明
此函数的输入参数与函数__wake_up( )的输入参数基本相同,详细信息参考__wake_up( )。
__wake_up_sync_key返回参数说明
此函数的返回结果是一个void型的变量,即没有任何返回结果。
__wake_up_sync_key实例解析
编写测试文件:__wake_up_sync_key.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>
MODULE_LICENSE("GPL");
/*全局变量定义*/
static wait_queue_head_t head; //等待队列头元素
struct task_struct * old_thread; //保存进程描述符信息
子进程处理函数定义:
int my_function(void * argc)
{
printk("in the kernel thread function! \n");
printk("the current pid is:%d\n", current->pid); //显示当前进程的PID值
/*显示父进程的状态*/
printk("the state of the init funcation is :%ld\n", old_thread->state);
__wake_up_sync_key(&head, TASK_ALL,0, NULL); //调用函数唤醒等待队列中的进程
// 显示函数调用之后的父进程的状态
printk("the state of the init function after __wake_up_sync_key is :%ld\n", old_thread->state);
printk("out the kernel thread function\n");
return 0;
}
模块加载函数定义:
static int __init __wake_up_sync_key_init(void)
{
char namefrm[]="__wake_up_sync_key.c%s"; //线程的输出类型名,在此无影响
long time_out; //保存schedule_timeout_uninterruptible( )的返回结果
struct task_struct * result; //保存新进程的信息
wait_queue_t data; //等待队列元素
printk("into __wake_up_sync_key_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; //记录当前进程的信息
wake_up_process(result); //唤醒新创建的线程
time_out=schedule_timeout_uninterruptible(1000*10); //让当前进程进入睡眠状态
//输出schedule_timeout_uninterruptible( )返回结果
printk("the schedule timeout is:%ld\n", time_out);
printk("out __wake_up_sync_key_init.\n");
return 0;
}
模块退出函数定义:
static void __exit __wake_up_sync_key_exit(void)
{
printk("Goodbye __wake_up_sync_key\n");
}
模块加载、退出函数调用:
module_init(__wake_up_sync_key_init);
module_exit(__wake_up_sync_key_exit);
实例运行结果及分析:
首先编译模块,执行命令insmod __wake_up_sync_key.ko插入内核模块,然后输入命令dmesg -c查看模块插入结果,会出现如图所示的结果。
结果分析:
由上图可知模块初始化进程的进程号为6207,新进程的进程号为6208。在新进程中函数__wake_up_sync_key( )执行前模块初始化进程的状态值为2,即处于不可中断的等待状态,因为进程中执行了函数schedule_timeout_uninterruptible( )。函数__wake_up_sync_key( )执行后,模块初始化进程的状态值变为0,并且函数schedule_timeout_uninterruptible( )的返回结果是10000,说明父进程是被强制唤醒的,而非等待超时唤醒。由此可以说明函数__wake_up_sync_key( )能够唤醒等待队列中的满足条件的进程,此条件是进程所处的状态在函数的第二个参数所定义的状态范围内。
进程状态说明:
对于进程能够处于的状态,在函数__wake_up( )的进程状态说明部分有详细的说明。