Linux内核线程创建

时间:2021-09-16 03:44:52

本文旨在简单介绍一下Linux内核线程:

先举个例子:

不插U盘,在Linux命令行中输入:ps -el;然后插上U盘,再次输入:ps -el

会发现多出了下面一行(当然还会有其他的,比如scsi相关的):

 F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
S - - ? :: usb-storage

usb-storage 就是U盘驱动程序(驱动程序是动态加载的)起来之后,由内核创建的内核线程。下面我们就来看一下它是如何被创建的。有关usb-storage的完整内容,以后学习USB驱动时再详解,今天只讨论内核是如何管理内核线程的创建的。

在启动过程中,Linux2.6.22.6/init/main.c::rest_init()会创建另外2个进程(1号进程kernel_init和2号进程kthreadd),今天我们要讨论的就是2号进程kthreadd,它是所有内核线程(比如上面的usb-storage)的父进程。

 static void noinline __init_refok rest_init(void)
__releases(kernel_lock)
{
int pid; kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); // 创建1号进程
numa_default_policy();
pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); // 创建2号进程 kthreadd
kthreadd_task = find_task_by_pid(pid);
unlock_kernel();
....
}

kthreadd()位于Linux2.6.22.6/kernel/kthread.c,今天我们主要就是分析这支文件。

kthreadd进程被创建之后就开始运行,我们看到他有一个死循环(for),他会一直去判断链表kthread_create_list中是否有内容,如果有,就根据链表的元素去创建一个内核线程。而函数kthread_create()会向链表kthread_create_list中插入元素(代码这里就不贴了)。

 int kthreadd(void *unused)
{
/* Setup a clean context for our children to inherit. */
kthreadd_setup(); current->flags |= PF_NOFREEZE; for (;;) {
set_current_state(TASK_INTERRUPTIBLE); // 设置进程状态: 可中断的等待状态
if (list_empty(&kthread_create_list)) // 如果链表为空
schedule(); __set_current_state(TASK_RUNNING); spin_lock(&kthread_create_lock);
while (!list_empty(&kthread_create_list)) {
struct kthread_create_info *create; create = list_entry(kthread_create_list.next,
struct kthread_create_info, list);
list_del_init(&create->list);
spin_unlock(&kthread_create_lock); create_kthread(create); // 他会调用kernel_thread完成真正的内核线程创建 spin_lock(&kthread_create_lock);
}
spin_unlock(&kthread_create_lock);
} return ;
}

U盘驱动程序的内核线程是如何被创建的呢? 就是通过下面这段代码(位于Linux2.6.22.6/driver/usb/storage/usb.c):

 /* Start up our control thread */
th = kthread_create(usb_stor_control_thread, us, "usb-storage"); //
if (IS_ERR(th)) {
printk(KERN_WARNING USB_STORAGE
"Unable to start control thread\n");
return PTR_ERR(th);
}

下面通过一张图来总结一下:

Linux内核线程创建