linux 内核 sync,进程调度 – Linux内核API __wake_up_sync_key

__wake_up_sync_key函数是Linux内核中一种高效唤醒等待队列中特定状态进程的技术,通过指定模式和同步特性,确保唤醒过程不引发额外CPU抢占。本文通过实例演示如何使用该函数,并解析其在进程状态管理和协作中的作用。
摘要由CSDN通过智能技术生成

__wake_up_sync_key函数功能描述:此函数用于唤醒等待队列中处于特定状态的进程,此特定状态由第二个参数mode给出。当进程的状态满足此特定状态时就有可能被唤醒,获得CPU资源,从而被调度执行。此函数唤醒的进程不会改变进程之前所在的CPU,不会引起额外的CPU的抢占,并且可以同步唤醒进程。

__wake_up_sync_key文件包含

#include

__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

#include

#include

#include

#include

#include

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查看模块插入结果,会出现如图所示的结果。

166c6d570a13c7c4f8513c1135459c90.png

结果分析:

由上图可知模块初始化进程的进程号为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( )的进程状态说明部分有详细的说明。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值