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

105 篇文章 2 订阅
84 篇文章 6 订阅

在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的链表下,如下图所示



  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值