详细解剖Linux进程管理

系统 Linux
本文给大家讲解linux进程管理的办法,例如:进程管理的分配有两种方式。第一种方式是通过一个哈希表,第二种方式是通过双链循环表。

学习进程时,你可能会遇到linux进程管理的问题,这里将介linux进程管理问题的解决方法,在这里拿出来和大家分享一下。

***进程数:在 Linux 内虽然进程都是动态分配的,但还是需要考虑***进程数。在内核内***进程数是由一个称为 max_threads 的符号表示的,它可以在 ./linux/kernel/fork.c 内找到。可以通过 /proc/sys/kernel/threads-max 的 proc 文件系统从用户空间更改此值。

现在,让我们来看看如何在 Linux进程管理。在很多情况下,进程都是动态创建并由一个动态分配的 task_struct 表示。一个例外是 init 进程本身,它总是存在并由一个静态分配的 task_struct 表示。在 ./linux/arch/i386/kernel/init_task.c 内可以找到这样的一个例子。

Linux 内所有linux进程管理的分配有两种方式。***种方式是通过一个哈希表,由 PID 值进行哈希计算得到;第二种方式是通过双链循环表。循环表非常适合于对任务列表进行迭代。由于列表是循环的,没有头或尾;但是由于 init_task 总是存在,所以可以将其用作继续向前迭代的一个锚点。让我们来看一个遍历当前任务集的例子。

任务列表无法从用户空间访问,但该问题很容易解决,方法是以模块形式向内核内插入代码。下面清单所示的是一个很简单的程序,它会迭代任务列表并会提供有关每个任务的少量信息(name、pid 和 parent 名)。注意,在这里,此模块使用 printk 来发出结果。要查看具体的结果,可以通过 cat 实用工具(或实时的 tail -f /var/log/messages)查看 /var/log/messages 文件。next_task 函数是 sched.h 内的一个宏,它简化了任务列表的迭代(返回下一个任务的 task_struct 引用)。

清单:发出任务信息的简单内核模块(procsview.c)
#include
#include
#include
int init_module( void ){
/* Set up the anchor point */
struct task_struct *task = &init_task;
/* Walk through the task list, until we hit the init_task again */do {
printk( KERN_INFO "*** %s [%d] parent %s\n",
task->comm, task->pid, task->parent->comm );
} while ( (task = next_task(task)) != &init_task );
return 0;
}
void cleanup_module( void ){
return;}

可以用清单所示的 Makefile 编译此模块。在编译时,可以用 insmod procsview.ko 插入模块对象,也可以用 rmmod procsview 删除它。

清单:用来构建内核模块的 Makefile
obj-m += procsview.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
插入后,/var/log/messages 可显示输出,如下所示。从中可以看到,这里有一个空闲任务(称为 swapper)和 init 任务(pid 1)。
Nov 12 22:19:51 mtj-desktop kernel: [8503.873310] *** swapper [0] parent swapper
Nov 12 22:19:51 mtj-desktop kernel: [8503.904182] *** init [1] parent swapper
Nov 12 22:19:51 mtj-desktop kernel: [8503.904215] *** kthreadd [2] parent swapper
Nov 12 22:19:51 mtj-desktop kernel: [8503.904233] *** migration/0 [3] parent kthreadd
...

注意,还可以标识当前正在运行的任务。Linux 维护一个称为 current 的符号,代表的是当前运行的进程(类型是 task_struct)。如果在 init_module 的尾部插入如下这行代码:
printk( KERN_INFO, "Current task is %s [%d], current->comm, current->pid );

会看到:
Nov 12 22:48:45 mtj-desktop kernel: [10233.323662] Current task is insmod [6538]

注意到,当前的任务是 insmod,这是因为 init_module 函数是在 insmod 命令执行的上下文运行的。current 符号实际指的是一个函数(get_current)并可在一个与 arch 有关的头部中找到(比如 ./linux/include/asm-i386/current.h 内找到)。

【编辑推荐】

  1. Linux shell学习之:unix/linux shell的发展历程
  2. Linux shell编程学习之一:什么是shell
  3. Linux系统实现SCSI硬盘热插拔及在线识别步骤
  4. 轻松了解Linux打印之CUPS软件
  5. 话说在win32下安装linux虚拟机
责任编辑:薛辈辈 来源: linux
相关推荐

2009-11-24 09:39:55

SUSE Linux

2010-04-26 10:24:12

Oracle ASM

2010-05-20 14:14:56

2010-05-07 16:21:08

Oracle Raw类

2010-03-08 14:40:27

Linux进程调度

2011-01-11 13:47:27

Linux管理进程

2023-03-05 16:12:41

Linux进程线程

2010-02-25 10:28:43

Linux进程管理

2010-06-11 16:57:37

Linux 查看进程

2023-03-02 23:50:36

Linux进程管理

2011-01-11 16:11:03

2009-12-15 18:27:51

Linux操作系统

2010-01-05 16:56:28

2014-08-01 15:38:37

Linux进程管理

2023-03-03 00:03:07

Linux进程管理

2009-12-23 13:17:36

Linux设备驱动

2011-01-18 11:15:19

LinuxLOG

2010-03-10 18:29:41

2021-06-15 08:02:55

Linux 进程管理

2022-11-09 08:12:07

点赞
收藏

51CTO技术栈公众号