Linux内核进程和线程组织模型 (基于Kernel 4.3-rc3)
2015-10-20 13:48
681 查看
在linux内核代码里面,看到有for_each_process()和for_each_process_thread()两个函数,不太明白怎么回事,就做了个代码实验
1. 验证代码
编译为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的链表下,如下图所示
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的链表下,如下图所示
相关文章推荐
- Linux性能评测工具之一:gprof篇介绍
- linux hosts的allow和deny
- Linux 0.12内核与现代内核在内存管理上的区别
- 虚拟机中centos联网
- centos7 编译python 退格 删除 字符不识别
- Linux的LVM(Logical Volume Manager)
- linux命令行常用快捷键
- Linux多线程基础学习(六)线程属性
- linux判断存储空间是否满
- linux代码段,数据段,BSS段, 堆,栈(二)
- centos 安装 GraphicsMagick
- python在linux(anaconda)的图形界面(snack)
- linux系统添加java和glassfish环境变量
- 硬盘MBR详细介绍
- linux iptables实现
- Linux进程和内核级进程的一些知识
- Linux系统下NTP协议的超级配置攻略
- Linux必学的60个命令
- linux压缩与归档工具
- Linux线程同步(条件变量和信号量)