本文旨在简单介绍一下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. Hadoop生态集群之HDFS

    一.HDFS是什么 HDFS是hadoop集群中的一个分布式的我文件存储系统.他将多台集群组建成一个集群,进行海量数据的存储.为超大数据集的应用处理带来了很多便利. 和其他的分布式文件存储系统相比他有 ...

  2. [LeetCode] 620. Not Boring Movies_Easy tag: SQL

    X city opened a new cinema, many people would like to go to this cinema. The cinema also gives out a ...

  3. js简易计算器底层运算逻辑(带撤销功能)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  4. 破解sublime的sftp

    http://www.dodobook.net/linux/2751,按照这个在Linux下操作(Windows下不行) 提示错误: File "/usr/lib/python2.7/sit ...

  5. 编译用到boost相关的东西,问题的解决;以及和googletest库

    编译https://github.com/RAttab/reflect, 发现需要gcc4.7以上的版本才行.于是编译安装最新的gcc-6.2.0, 过程算顺利. http://www.linuxfr ...

  6. Ecshop 表结构 字段说明

    ecs_account_log 用户帐号情况记录表,包括资金和积分等 log_id mediumint 自增ID号user_id mediumint 用户登录后保存在session中的id号,跟use ...

  7. linux du查看文件所占大小

    Linux du命令也是查看使用空间的,但是与df命令不同的是Linux du命令是对文件和目录磁盘使用的空间的查看,还是和df命令有一些区别的. 1.命令格式: du [选项][文件] 2.命令功能 ...

  8. ES6之字符串扩展

    ES6字符串新增的常用方法: 1. includes(): 字符串中是否包含某个字符或字符串, 包含的两个字符必须是相连的 let str = 'hello, world' str.includes( ...

  9. LeetCode112.路径总和

    给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和. 说明: 叶子节点是指没有子节点的节点. 示例: 给定如下二叉树,以及目标和 sum = 22 ...

  10. python windows 安装gensim

    安装gensim要确定numpy和scipy安装 再安装gensim