本文旨在简单介绍一下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内核线程创建的更多相关文章

  1. Java线程与Linux内核线程的映射关系(转)

    Java线程与Linux内核线程的映射关系 Java线程与Linux内核线程的映射关系Linux从内核2.6开始使用NPTL (Native POSIX Thread Library)支持,但这时线程 ...

  2. linux内核中创建线程方法

    1.头文件 #include <linux/sched.h> //wake_up_process() #include <linux/kthread.h> //kthread_ ...

  3. linux内核中创建线程方法【转】

    本文转载自:https://www.cnblogs.com/Ph-one/p/6077787.html 1.头文件 #include <linux/sched.h> //wake_up_p ...

  4. Linux内核线程的思考与总结

    1.内核线程,只是一个称呼,实际上就是一个进程,有自己独立的TCB,参与内核调度,也参与内核抢占. 这个进程的特别之处有两点,第一.该进程没有前台.第二.永远在内核态中运行. 2.创建内核线程有两种方 ...

  5. Linux内核线程kernel thread详解--Linux进程的管理与调度(十)

    内核线程 为什么需要内核线程 Linux内核可以看作一个服务进程(管理软硬件资源,响应用户进程的种种合理以及不合理的请求). 内核需要多个执行流并行,为了防止可能的阻塞,支持多线程是必要的. 内核线程 ...

  6. Linux内核分析-创建新进程的过程

    分析Linux内核创建一个新进程的过程 task_struct结构体分析 struct task_struct{ volatile long state; //进程的状态 unsigned long ...

  7. Linux内核分析— —创建新进程的过程

    分析Linux内核创建一个新进程的过程 实验过程 要求:使用gdb跟踪分析一个fork系统调用内核处理函数sys_clone ,验证对Linux系统创建一个新进程的理解,推荐在实验楼Linux虚拟机环 ...

  8. linux内核线程,进程,线程

    http://blog.csdn.net/dyllove98/article/details/8917197 Linux对于内存的管理涉及到非常多的方面,这篇文章首先从对进程虚拟地址空间的管理说起.( ...

  9. Linux内核线程kernel thread详解--Linux进程的管理与调度(十)【转】

    转自:http://blog.csdn.net/gatieme/article/details/51589205 日期 内核版本 架构 作者 GitHub CSDN 2016-06-02 Linux- ...

随机推荐

  1. SpringBoot java.lang.IllegalArgumentException: Request header is too large

    在application.properties##tomcat 请求设置server.max-http-header-size=1048576server.tomcat.max-connections ...

  2. Py中enumerate方法【转载】

    转自:http://www.runoob.com/python/python-func-enumerate.html enumerate(sequence, [start=0]) sequence - ...

  3. jsp内置对象学习记录

    1.session,是一个会话保留在服务器端的对象(默认保留时间为30分钟),所以我们可以在session里面放用户信息以便后续的访问便利(缺点:cookie劫持,导致用户数据泄露).案例:(1)同个 ...

  4. iOS 崩溃分析

    崩溃统计分析,在APP中是非常常见一种优化APP,发现APP的BUG的方式. 1.异常处理 可通过try catch 方式处理,如果发生异常,会走catch ,最终走fianlly.对一些我们不想他崩 ...

  5. Reveal使用

    本人手机是7.1的,reveal2.0以后不支持8.0以下,没办法,这里只能使用reveal1.6. 这里提醒一下,reveal2.0以后libReavel.lib改名了,. https://reve ...

  6. hibernate.validator.constraints.NotEmpty校验请求参数报错java.lang.NoClassDefFoundError: javax/el/PropertyNotFoundException

    spring maven项目,使用hibernate validator 注解形式校验客户端的请求参数. hibernate-validator版本:5.0.2.Final validation-ap ...

  7. 008-副文本编辑器UEditor

    <!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...

  8. 关于 LD_LIBRARY_PATH 这个环境变量

    这个变量中可以保存linux寻找库时搜索的路径,按照一篇文章中的介绍,不应该设置这个变量.文章的重点如下: 1. 不要设置这个变量. 2. Solaris中,在编译时,使用 -L 选项指定编译时库的搜 ...

  9. mysql存储过程或函数中传入参数与表字段名相同引发的悲剧

    真实案例.如下的一个存储过程: create procedure Apple(in user_id int) begin delete from users where user_id = user_ ...

  10. css中块级元素、内联元素(行内元素、内嵌元素)

    Block element 块级元素    顾名思义就是以块显示的元素,高度宽度都是可以设置的.比如我们常用 的<div>.<p>.<ul>默认状态下都是属于块级元 ...