您的位置:首页 > 运维架构 > Linux

Linux内核进程和线程组织模型 (基于Kernel 4.3-rc3)

2015-10-20 13:48 681 查看
在linux内核代码里面,看到有for_each_process()和for_each_process_thread()两个函数,不太明白怎么回事,就做了个代码实验

1. 验证代码

/*****************************************************************
* Copyright (C) 2015 Intel Technology Co.,Ltd.*
******************************************************************
* lsitprocess.c
*
* DESCRIPTION:
* 	列出所有的进程/线程
* AUTHOR:
* 刘峰 11579502
*
* CREATED DATE:
* 2015年09月17日
* REVISION:
* 1.0
*
* MODIFICATION HISTORY
* --------------------
* $Log:$
* 刘峰 2015年09月17日  Creation
*****************************************************************/

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/proc_fs.h>
#include <linux/time.h>
#include <linux/hrtimer.h>
#include <linux/kvm_para.h>
#include <linux/seq_file.h>
#include <asm/uaccess.h>
#include <stdbool.h>
#include <asm/msr.h>
#include <linux/slab.h>
#include <asm/page_64_types.h>

#include <linux/sched.h>

#define LOCAL		static

#define KMOD_DBGDUMP(fmt, args...) printk(KERN_DEBUG "LISTPROCESS[%d] "fmt" \r\n", __LINE__, args);
#define KMOD_RAWDUMP(args...) printk(args); /* RAW 信息输出 */

LOCAL struct proc_dir_entry *proc_file = NULL;
LOCAL int32_t kmod_action_sw = 8;

#define TEST_CASE_1	(1)
#define TEST_CASE_2	(2)
#define TEST_CASE_3	(3)

#define KMODSEPC

/******************************************************************************
* DESCRIPTION:
*       利用list_for_each_entry进行打印
* INPUTS:
*       none
* OUTPUTS:
*       none
* RETURNS:
*       none
******************************************************************************/
void listprocess_test_case_1(void){
struct task_struct *task = NULL;
struct task_struct *p = NULL;
struct list_head *pos;
int count = 0;

printk("list_for_each\n");
printk("PID\tCOMM\n");
task = &init_task;
list_for_each(pos, &task->tasks ) {
p = list_entry(pos, struct task_struct, tasks);
count++;
printk("%d\t%s\n", p->pid, p->comm);
}
printk("Total process %d\n", count);
return;
}

/******************************************************************************
* DESCRIPTION:
*       利用for_each_process进行打印
* INPUTS:
*       none
* OUTPUTS:
*       none
* RETURNS:
*       none
******************************************************************************/
void listprocess_test_case_2(void){
struct task_struct *tsk;
int count = 0;

printk("for_each_process\n");
printk("PID\tCOMM\n");
for_each_process(tsk){
count++;
printk("%d\t%s\n", tsk->pid, tsk->comm);
}
printk("Total process %d\n", count);

return;
}

/******************************************************************************
* DESCRIPTION:
*       利用for_each_process_thread进行打印
* INPUTS:
*       none
* OUTPUTS:
*       none
* RETURNS:
*       none
******************************************************************************/

void listprocess_test_case_3(void){
struct task_struct *p;
struct task_struct *t;
int count = 0;

printk("for_each_process_thread\n");
printk("PID\tCOMM\n");
for_each_process_thread(p,t){
count++;
printk("%d\t%s\n", t->pid, t->comm);
}
printk("Total thread %d\n", count);

return;
}

#if 1
KMODSEPC
#endif

/******************************************************************************
* DESCRIPTION:
*       PROC 文件读方法
* INPUTS:
*       none
* OUTPUTS:
*       none
* RETURNS:
*       none
******************************************************************************/
LOCAL int kmod_proc_read(struct seq_file * m, void * v)
{
seq_printf(m, "Entering kmod_proc_read\n");
return 0;
}

/******************************************************************************
* DESCRIPTION:
*       PROC 文件写方法
* INPUTS:
*       none
* OUTPUTS:
*       none
* RETURNS:
*       none
******************************************************************************/
static ssize_t kmod_proc_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos)
{
char debug_string[sizeof("4294967295")];
kmod_action_sw = 0;

KMOD_DBGDUMP("%s","Entering kmod_proc_write");

if (count >= sizeof(debug_string))
return -EINVAL;

if (copy_from_user(debug_string, buffer, count))
return -EFAULT;

debug_string[count] = '\0';
if (sscanf(debug_string, "%d", &kmod_action_sw) != 1)
return -EINVAL;

KMOD_DBGDUMP("write kmod_action_sw = %d\n", kmod_action_sw);

/*运行测试用例*/
switch(kmod_action_sw)
{
case TEST_CASE_1:
listprocess_test_case_1();
break;
case TEST_CASE_2:
listprocess_test_case_2();
break;
case TEST_CASE_3:
listprocess_test_case_3();
break;
default:
KMOD_DBGDUMP("%s","not support timer test case");
}

return count;

return count;
}

/******************************************************************************
* DESCRIPTION:
*       PROC 文件打开方法
* INPUTS:
*       none
* OUTPUTS:
*       none
* RETURNS:
*       none
******************************************************************************/
static int kmod_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, kmod_proc_read, NULL);
}

/*
* PROC文件操作列表
*/
LOCAL const struct file_operations kmod_proc_fops = {
.open    = kmod_proc_open,
.read    = seq_read,
.llseek  = seq_lseek,
.release = seq_release,
.write   = kmod_proc_write,
};

/******************************************************************************
* DESCRIPTION:
*       初始化PROC 目录
* INPUTS:
*       none
* OUTPUTS:
*       none
* RETURNS:
*       none
******************************************************************************/
LOCAL int kmod_proc_init(void)
{
proc_file = proc_create("listprocess", 0666, NULL, &kmod_proc_fops);
if(!proc_file){
KMOD_DBGDUMP("%s","Can't create /proc/listprocess\n");
}

KMOD_DBGDUMP("%s","kmod_proc_init OK\n");
return 0;
}

/******************************************************************************
* DESCRIPTION:
*       删除PROC 目录
* INPUTS:
*       none
* OUTPUTS:
*       none
* RETURNS:
*       none
******************************************************************************/
LOCAL void kmod_proc_remove(void)
{
remove_proc_entry("listprocess",NULL);
return;
}

/******************************************************************************
* DESCRIPTION:
*       模块初始化函数
* INPUTS:
*       none
* OUTPUTS:
*       none
* RETURNS:
*       none
******************************************************************************/
LOCAL int32_t __init listprocess_init(void)
{
kmod_proc_init();

KMOD_DBGDUMP("%s","glistprocess_init init OK\n");
return 0;
}

/******************************************************************************
* DESCRIPTION:
*       模块卸载函数
* INPUTS:
*       none
* OUTPUTS:
*       none
* RETURNS:
*       none
******************************************************************************/
LOCAL void __exit listprocess_exit(void)
{
kmod_proc_remove();

KMOD_DBGDUMP("%s","listprocess_exit exit OK\n");
return;
}

MODULE_LICENSE ( "GPL" );
module_init (listprocess_init);
module_exit (listprocess_exit);


编译为listprocess.ko模块

2. 实验步骤

启动一个多线程的程序test
[root@localhost ~]# ps -efL | grep test
root       6569   6410   6569  0    2 22:52 pts/0    00:00:00 ./test

root       6569   6410   6570  0    2 22:52 pts/0    00:00:00 ./test
root       7754   7658   7754  0    1 23:15 pts/2    00:00:00 grep --color=auto test

插入模块并验证
[root@localhost ~]# echo 2 > /proc/listprocess

[root@localhost ~]# dmesg | grep test
[ 3198.656973] 6569     test
[root@localhost ~]# echo 3 > /proc/listprocess

[root@localhost ~]# dmesg -c | grep test

[ 3229.872902] 6569     test
[ 3229.872903] 6570     test

3. 结论
系统中所有的进程都组织在init_task的tasks链表下面,每个进程的线程组织在每个进程task_sturct->signal的链表下,如下图所示

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: