Linux内核中进程0的主要任务是什么?

Linux内核中进程0的主要任务是什么?,第1张

总结一下有如下几个要点:

1.

进程0是所有其他进程的祖先,

也称作idle进程或swapper进程.

2.

进程0是在系统初始化时由kernel自身从无到有创建.

3.

进程0的数据成员大部分是静态定义的,即由预先定义好的INIT_TASK,

INIT_MM等宏初始化.

进程0的描述符init_task定义在arch/arm/kernel/init_task.c,由INIT_TASK宏初始化。

init_mm等结构体定义在include/linux/init_task.h内,为init_task成员的初始值,分别由对应的初始化宏如INIT_MM等初始化

Process

1

进程0最终会通过调用kernel_thread创建一个内核线程去执行init函数,这个新创建的内核线程即Process

1(这时还是共享着内核线程0的资源属性如地址空间等)。init函数继续完成剩余的内核初始化,并在函数的最后调用execve系统调用装入用户空间的可执行程序/sbin/init,这时进程1就拥有了自己的属性资源,成为一个普通进程(init进程)。至此,内核初始化和启动过程结束。下面就进入了用户空间的初始化,最后运行shell登陆界面。(注:Init进程一直存活,因为它创建和监控在 *** 作系统外层执行的所有进程的活动。)

——————

这段对进程0的描述引用自《Understanding

The

Linux

Kernel

-

Third

Edtion》

The

ancestor

of

all

processes,

called

process

0,

the

idle

process,

or,

for

historical

reasons,

the

swapper

process,

is

a

kernel

thread

created

from

scratch

during

the

initialization

phase

of

Linux.

This

ancestor

process

uses

the

following

statically

allocated

data

structures

(data

structures

for

all

other

processes

are

dynamically

allocated)

1.头文件

#include <linux/sched.h> //wake_up_process()

#include <linux/kthread.h>//kthread_create()、kthread_run()

#include <err.h> //IS_ERR()、PTR_ERR()

2.实现

2.1创建线程

在模块初始化时,可以进行线程的创建。使用下面的函数和宏定义:

struct task_struct *kthread_create(int (*threadfn)(void *data),

void *data,

const char namefmt[], ...)

#define kthread_run(threadfn, data, namefmt, ...) \

({\

struct task_struct *__k\

= kthread_create(threadfn, data, namefmt, ## __VA_ARGS__)\

if (!IS_ERR(__k))\

wake_up_process(__k) \

__k\

})

例如:

static struct task_struct *test_task

static int test_init_module(void)

{

int err

test_task = kthread_create(test_thread, NULL, "test_task")

if(IS_ERR(test_task)){

printk("Unable to start kernel thread. ")

err = PTR_ERR(test_task)

test_task = NULL

return err

}

wake_up_process(test_task)

return 0

}

module_init(test_init_module)

2.2线程函数

在线程函数里,完成所需的业务逻辑工作。主要框架如下所示:

int threadfunc(void *data){

while(1){

set_current_state(TASK_UNINTERRUPTIBLE)

if(kthread_should_stop()) break

if(){//条件为真

//进行业务处理

}

else{//条件为假

//让出CPU运行其他线程,并在指定的时间内重新被调度

schedule_timeout(HZ)

}

}

return 0

}

2.3结束线程

在模块卸载时,可以结束线程的运行。使用下面的函数:

int kthread_stop(struct task_struct *k)

例如:

static void test_cleanup_module(void)

{

if(test_task){

kthread_stop(test_task)

test_task = NULL

}

}

module_exit(test_cleanup_module)

3.注意事项

(1) 在调用kthread_stop函数时,线程函数不能已经运行结束。否则,kthread_stop函数会一直进行等待。

(2) 线程函数必须能让出CPU,以便能运行其他线程。同时线程函数也必须能重新被调度运行。在例子程序中,这是通过schedule_timeout()函数完成的。

4.性能测试

可以使用top命令来查看线程(包括内核线程)的CPU利用率。命令如下:

top –p 线程号

可以使用下面命令来查找线程号:

ps aux|grep 线程名

可以用下面的命令显示所有内核线程:

ps afx

注:线程名由kthread_create函数的第三个参数指定

在分析usb_hub_init()的代码的时候,忽略掉了一部份.

代码片段如下所示:

int usb_hub_init(void)

{

……

khubd_task = kthread_run(hub_thread, NULL, "khubd")

……

}

Kthread_run() 是kernel中用来启动一个新kernel线程的接口,它所要执行的函数就是后面跟的第一个参数.在这里,也就是hub_thread().另外,顺带 提一句,要终止kthread_run()创建的线程,可以调用kthread_stop().

1. 进程0是所有其他进程的祖先, 也称作idle进程或swapper进程.

2. 进程0是在系统初始化时由kernel自身从无到有创建.

3. 进程0的数据成员大部分是静态定义的,即由预先定义好的INIT_TASK, INIT_MM等宏初始化.进程0的描述符init_task定义在arch/arm/kernel/init_task.c,由INIT_TASK宏初始化。 i

nit_mm等结构体定义在include/linux/init_task.h内,为init_task成员的初始值,分别由对应的初始化宏如INIT_MM等初始化Process 1进程0最终会通过调用kernel_thread创建一个内核线程去执行init函数,这个新创建的内核线程即Process 1(这时还是共享着内核线程0的资源属性如地址空间等)。

init函数继续完成剩余的内核初始化,并在函数的最后调用execve系统调用装入用户空间的可执行程序/sbin/init,这时进程1就拥有了自己的属性资源,成为一个普通进程(init进程)。

至此,内核初始化和启动过程结束。下面就进入了用户空间的初始化,最后运行shell登陆界面。

(注:Init进程一直存活,因为它创建和监控在 *** 作系统外层执行的所有进程的活动。)

——————这段对进程0的描述引用自《Understanding The Linux Kernel - Third Edtion》

The ancestor of all processes, called process 0, the idle process, or, for historical reasons, the swapper process, is a kernel thread created from scratch during the initialization phase of Linux. This ancestor process uses the following statically allocated data structures (data structures for all other processes are dynamically allocated)


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7420921.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-05
下一篇 2023-04-05

发表评论

登录后才能评论

评论列表(0条)

保存