Linux内核API完全参考手册(第2版)
上QQ阅读APP看书,第一时间看更新

3.10 函数:pid_task( )

文件包含:

        #include <linux/pid.h>

函数定义:

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

函数定义格式:struct task_struct *pid_task(struct pid *pid, enum pid_type)

函数功能描述:

此函数获取任务的任务描述符信息,此任务在进程pid的使用链表中,并且搜索的链表的起始元素的下标为参数type的值。

输入参数说明:

参数pid是struct pid类型的指针变量,保存进程描述符信息,其定义及详细解释请读者自行参考本章函数f ind_get_pid( )分析文档的返回参数说明部分。

参数type是pid_type型变量,此变量是一个枚举型变量,定义如下:

        enum pid_type
        {
            PIDTYPE_PID,     //进程的进程号
            PIDTYPE_PGID,    //进程组领头进程的进程号
            PIDTYPE_SID,     //会话领头进程的进程号
            PIDTYPE_MAX
        };

返回参数说明:

此函数的返回结果是struct task_struct结构体类型的变量,保存对应的任务描述符的信息,其定义参见内核源码文件linux-3.19.3/include/linux/sched.h,内核源码注释比较详细,请读者自行分析。

实例解析:

编写测试文件:pid_task.c

头文件引用:

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

模块加载函数定义:

        static int __init pid_task_init(void)
        {
            printk("into pid_task_init.\n");
            struct pid * kpid=find_get_pid(current->pid);           //获取当前进程的描述符信息
            struct task_struct * task=pid_task(kpid, PIDTYPE_PID); //获取进程的任务描述符信息
            printk("the state of the task is:%d\n", task->state);    //显示任务当前所处的状态
            printk("the pid of the task is:%d\n", task->pid);        //显示任务的进程号
            printk("the tgid of the task is:%d\n", task->tgid);      //显示任务的线程组号

            printk("the pid of current thread is:%d\n", current->pid); //显示当前进程的进程号
            printk("out pid_task_init.\n");
            return 0;
        }

模块退出函数定义:

        static void __exit pid_task_exit(void)
        {
            printk("Goodbye   pid_task\n");
        }

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

        module_init(pid_task_init);
        module_exit(pid_task_exit);

实例运行结果及分析:

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

图3-10 插入pid_task模块系统输出信息

结果分析:

由图3-10可以得出任务处在runnable(可运行)状态,因为state的值为0。state可能的取值为-1、0、大于0,等于-1处于不可运行状态,等于0处于可运行状态,大于0处于停止运行状态。任务的进程号和线程组号相同,并且等于当前进程的进程号,对于一个任务其包含的进程的进程号一般与其线程组号相同。