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)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)