This commit is contained in:
gatieme
2016-06-05 13:55:22 +08:00
parent 0de75bc17a
commit d9b4941c3b
2 changed files with 58 additions and 3 deletions
@@ -109,8 +109,6 @@ struct task_struct
使用kthread_run,与kthread_create不同的是,其创建新线程后立即唤醒它,其本质就是先用kthread_create创建一个内核线程,然后通过wake_up_process唤醒它
内核线程会出现在系统进程列表中, 但是在ps的输出中进程名command由方括号包围, 以便与普通进程区分。
##2号进程kthreadd的诞生
-------
@@ -145,6 +143,17 @@ Linux中的workqueue机制就是为了简化内核线程的创建。通过kthrea
</font>
内核线程会出现在系统进程列表中, 但是在ps的输出中进程名command由方括号包围, 以便与普通进程区分。
如下图所示, 我们可以看到系统中, 所有内核线程都用[]标识, 而且这些进程父进程id均是2, 而2号进程kthreadd的父进程是0号进程
>使用ps -eo pid,ppid,command
![ps查看内核线程](./images/ps-eo.jpg)
##kernel_thread
-------
@@ -208,12 +217,22 @@ extern void daemonize(void);
<font color=0x00ffff>
延后内核的创建工作, 将内核线程的创建工作交给一个内核线程来做, 即kthreadd 2号进程
但是在kthreadd还没创建之前, 我们只能通过kernel_thread这种方式去创建,
但是在kthreadd还没创建之前, 我们只能通过kernel_thread这种方式去创建
</font>
同时kernel_thread的实现也改为由_do_fork(早期内核中是do_fork)来实现, 参见[kernel/fork.c](http://lxr.free-electrons.com/source/kernel/fork.c?v=4.5#L1779)
`
``c
pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
{
return _do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn,
(unsigned long)arg, NULL, NULL, 0);
}
```
##kthread_create
-------
```c
struct task_struct *kthread_create_on_node(int (*threadfn)(void *data),
void *data,
@@ -253,3 +272,39 @@ struct task_struct *kthread_create_on_node(int (*threadfn)(void *data),
使用kthread_run,与kthread_create不同的是,其创建新线程后立即唤醒它,其本质就是先用kthread_create创建一个内核线程,然后通过wake_up_process唤醒它
#内核线程的退出
-------
线程一旦启动起来后,会一直运行,除非该线程主动调用do_exit函数,或者其他的进程调用kthread_stop函数,结束线程的运行。
```c
int kthread_stop(struct task_struct *thread);
```
kthread_stop() 通过发送信号给线程。
如果线程函数正在处理一个非常重要的任务,它不会被中断的。当然如果线程函数永远不返回并且不检查信号,它将永远都不会停止。
在执行kthread_stop的时候,目标线程必须没有退出,否则会Oops。原因很容易理解,当目标线程退出的时候,其对应的task结构也变得无效,kthread_stop引用该无效task结构就会出错。
为了避免这种情况,需要确保线程没有退出,其方法如代码中所示:
```c
thread_func()
{
// do your work here
// wait to exit
while(!thread_could_stop())
{
wait();
}
}
exit_code()
{
kthread_stop(_task); //发信号给task,通知其可以退出了
}
```
这种退出机制很温和,一切尽在thread_func()的掌控之中,线程在退出时可以从容地释放资源,而不是莫名其妙地被人“暗杀”。
Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB