Linux学习笔记之内核线程
标签:内核c99createwarninginuxoneresstrong驱动
本文旨在简单介绍一下Linux内核线程:
先举个例子:
不插U盘,在Linux命令行中输入:ps -el;然后插上U盘,再次输入:ps -el
会发现多出了下面一行(当然还会有其他的,比如scsi相关的):
1 F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
2 1 S 0 2749 2 0 80 0 – 0 – ? 00:00:00 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)的父进程。
1 static void noinline __init_refok rest_init(void)
2 __releases(kernel_lock)
3 {
4 int pid;
5
6 kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); // 创建1号进程
7 numa_default_policy();
8 pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); // 创建2号进程 kthreadd
9 kthreadd_task = find_task_by_pid(pid);
10 unlock_kernel();
11 ….
12 }
kthreadd()位于Linux2.6.22.6/kernel/kthread.c,今天我们主要就是分析这支文件。
kthreadd进程被创建之后就开始运行,我们看到他有一个死循环(for),他会一直去判断链表kthread_create_list中是否有内容,如果有,就根据链表的元素去创建一个内核线程。而函数kthread_create()会向链表kthread_create_list中插入元素(代码这里就不贴了)。
1 int kthreadd(void *unused)
2 {
3 /* Setup a clean context for our children to inherit. */
4 kthreadd_setup();
5
6 current->flags |= PF_NOFREEZE;
7
8 for (;;) {