Linux内核 wake_up_process()

函数:wake_up_process( )

文件包含:

        #include <linux/sched.h>

函数定义:

在内核源码中的位置:linux-3.19.3/kernel/sched/core.c

函数定义格式:

int wake_up_process(struct task_struct *tsk)

函数功能描述:

此函数用于唤醒处于睡眠状态的进程,使进程由睡眠状态变为RUNNING状态,从而能够被CPU重新调度执行。

输入参数说明:

此函数的输入参数为进程的描述符信息,保存进程的一些基本信息,此结构体的定义见文件linux-3.19.3/include/linux/sched.h,内核注释比较详细。

返回参数说明:

此函数的返回结果是int型的变量,代表唤醒进程的情况,可能的取值是0或1。返回1代表当前进程不是处于RUNNING状态,唤醒进程成功;返回0代表当前进程处于RUNNING状态或唤醒进程失败。

实例解析:

编写测试文件: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;
}

模块加载函数定义:

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,会出现如图所示的结果。

Linux内核 wake_up_process()

结果分析:

由图可以看出在模块初始进程运行的过程中,新进程被调度执行了,此时模块初始进程的状态输出值是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( )的进程状态说明部分有详细的说明。

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!