快速业务通道

Linux操作系统 进程管理剖析

作者 佚名技术 来源 Linux系统 浏览 发布时间 2012-05-11
下文切换后的存储(硬件注册表、程序计数器等).

进程管理

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

最大进程数

在 Linux 内虽然进程都是动态分配的,但还是需要考虑最大进程数.在内核内最大进程数是由一个称为

Empire CMS,phome.net
max_threads 的符号表示的,它可以在 ./linux/kernel/fork.c 内找到.可以通过 /proc/sys/kernel/threads-max 的 proc 文件系统从用户空间更改此值.

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

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


清单 2. 发出任务信息的简单内核模块(procsview.c)

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>

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 %sn",
task->comm, task->pid, task->parent->comm );

} while ( (task = next_task(task)) != &init_task );

return 0;

}

void cleanup_module( void )
{
return;
}

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


清单 3. 用来构建内核模块的 Makefile

Empire CMS,phome.net

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]

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号