Linux内核API finish_wait

finish_wait函数功能描述:此函数的功能如下:

1)更改当前进程的状态,将当前进程置于TASK_RUNNING状态。

2)如果此函数的第二个参数在此函数的第一个参数所代表的等待队列中,则将其从此等待队列中删除,否则不进行删除操作,函数返回。

finish_wait文件包含

#include <linux/wait.h>

finish_wait函数定义

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

函数定义格式:

void f inish_wait(wait_queue_head_t *q, wait_queue_t *wait)

finish_wait输入参数说明

此函数的第一个输入参数是wait_queue_head_t类型的指针,代表等待队列的头指针,其定义及详细信息考__wake_up( )

此函数的第二个输入参数是wait_queue_t类型的指针,代表等待队列中的一个元素,其定义及详细信息参考abort_exclusive_wait( )

finish_wait返回参数说明

此函数的返回值类型是void,即不返回任何类型的值。

finish_wait实例解析

编写测试文件:f inish_wait.c

头文件引用:

#include <linux/module.h>
#include <linux/sched.h>
#include <linux/list.h>
#include <linux/kthread.h>
MODULE_LICENSE("GPL");

子进程处理函数定义:

int my_function(void * argc)
{
    printk("in the kernel thread function! \n");
    printk("the current pid is:%d\n", current->pid);     //显示当前进程的进程号
    printk("out the kernel thread function\n");
    return 0;
}

模块加载函数定义:

static int __init finish_wait_init(void)
{
    /*一些局部变量定义*/
    struct task_struct * result, * result1;
    char namefrm[] = "finish_wait";
    char namefrm1[] = "finish_wait1";
    int   wait_queue_num=0;
    wait_queue_head_t head;
    wait_queue_t data, data1, *curr, *next;
    printk("into finish_wait_init.\n");
    /*创建新进程,用于加入等待队列*/
    result=kthread_create_on_node(my_function, NULL, -1, namefrm);
    result1=kthread_create_on_node(my_function, NULL, -1, namefrm1);
    wake_up_process(result);
    wake_up_process(result1);
    init_waitqueue_head(&head);                        //初始化等待队列头指针
    init_waitqueue_entry(&data, result);               //用新进程初始化等待队列元素
    data.task_list.next=&data.task_list;               //初始化等待队列链表的next字段的值
    printk("the state of the current thread is:%ld\n", current->state);
                                                       //显示当前进程的状态值
    prepare_to_wait(&head, &data,130);                 //将新进程加入等待队列中
    printk("the state of the current thread is:%ld\n", current->state);
                                                       //显示当前进程的状态值
    init_waitqueue_entry(&data1, result1);             //用新进程初始化等待队列元素
    data1.task_list.next=&data1.task_list;             //初始化等待队列链表的next字段的值
    prepare_to_wait_exclusive(&head, &data1,2);        //将新进程加入等待队列中
    printk("the state of the current thread is:%ld\n", current->state);
                                                       //显示当前进程的状态值
    /*显示等待队列中的进程的PID值及等待队列中元素的flags值*/
    list_for_each_entry_safe(curr, next, &(head.task_list), task_list)
    {
        wait_queue_num++;                              //累加等待队列中的元素个数
        printk("the flag value of the current data of the waitqueue is:%d\n", curr->flags);                                          //显示字段flags的值
        printk("the pid value of the current data of the waitqueue is:%d\n", ((struct task_struct *)(curr->private))->pid);        //显示PID值
    }
    printk("the value of the wait_queue_num is :%d\n", wait_queue_num);
                                                       //显示当前等待队列中的元素个数
    finish_wait(&head, &data1);                        //调用函数删除等待队列中的一个元素
    printk("the state of the current thread is:%ld\n", current->state);
                                                       //显示函数调用之后当前进程的PID值
    wait_queue_num=0;
    /*显示函数调用之后等待队列中进程的PID值及等待队列中元素的flags值*/
    list_for_each_entry_safe(curr, next, &(head.task_list), task_list)
    {
        wait_queue_num++;                              //累加等待队列中的元素个数
        printk("the flag value of the current data of the waitqueue is:%d\n", curr->flags);                                           //显示字段flags的值
        printk("the pid value of the current data of the waitqueue is:%d\n", ((struct task_struct *)(curr->private))->pid);        //显示PID值
    }
    printk("the value of the wait_queue_num is :%d\n", wait_queue_num);
                                                       //显示函数调用之后等待队列中的元素个数
    printk("the pid of new thread is :%d\n", result->pid);
                                                  //显示函数kernel_thread( )的返回结果
    printk("the pid of new thread1 is :%d\n", result1->pid);
    printk("the current pid is:%d\n", current->pid);  //显示当前进程的PID值
    printk("out finish_wait_init.\n");
    return 0;
}

模块退出函数定义:

static void __exit finish_wait_exit(void)
{
    printk("Goodbye finish_wait\n");
}

模块加载、退出函数调用:

module_init(finish_wait_init);
module_exit(finish_wait_exit);

实例运行结果及分析:

首先编译模块,执行命令insmod finish_wait.ko插入内核模块,然后输入命令dmesg -c查看模块插入结果,会出现如图所示的结果。

Linux内核API finish_wait

结果分析:

由上图可以看出在函数finish_wait( )执行之前,当前进程的状态为2,等待队列中的元素的个数为2,函数执行之后,当前进程的状态变为0,等待队列中的元素个数变为1,由此可以说明函数finish_wait( )的作用。

说明:
在函数finish_wait( )执行之前设置当前进程的状态是没有什么特殊意义的,只是为了说明函数finish_wait( )能够更改当前进程的状态,使其处于TASK_RUNNING状态。

进程状态说明:

对于进程能够处于的状态,在函数__wake_up( )的进程状态说明部分有详细的说明。

赞(1)
未经允许不得转载:极客笔记 » Linux内核API finish_wait
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址