博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux内核-内核线程
阅读量:6995 次
发布时间:2019-06-27

本文共 2951 字,大约阅读时间需要 9 分钟。

         线程分类:内核线程、用户线程(指不需要内核支持而完全建立在用户空间的线程库,这种线程效率高,由于Linux内核没有轻量级进程(线程)的概念,因此不能独立的对用户线程进行调度,而是由一个线程运行库来组织线程的调度)和轻量级线程(内核线程的高级抽象,大多数操作涉及到系统调用,效率不高)。

         传统的Unix系统把一些重要的任务委托给周期性的执行进程,这些任务包括刷新磁盘高速缓存,交换出不用的页框,维护网络连接等。这些线程只运行在内核态(普通进程既可以运行在内核态,也可以运行在用户态),内核线程只运行在内核态,所以只使用大于PAGE_OFFSET的线性地址空间。现代操作系统把它们的函数委托给内核线程,内核线程不受不必要的用户态上下文拖累。内核线程的使用是廉价的,唯一使用的资源就是内核栈和上下文切换时保存寄存器的空间。

        内核线程(thread)或叫守护进程(daemon)

创建内核线程

         kernel_thread()函数创建一个新的内核线程,它接受的参数:所要执行的内核函数地址(fn)、要传递给函数的参数(arg)、一组clone标志(flags)。该函数的本质上是调用

 

do_fork(flags|CLONE_VM|CLONE_UNTRACED),0,pregs,0,NULL,NULL);//pregs表示内核栈的地址//CLONE_VM;避免复制进程页表 pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags){     struct pt_regs regs;     memset(®s, 0, sizeof(regs));     regs.ARM_r1 = (unsigned long)arg;     regs.ARM_r2 = (unsigned long)fn;     regs.ARM_r3 = (unsigned long)do_exit;     regs.ARM_pc = (unsigned long)kernel_thread_helper;     regs.ARM_cpsr = SVC_MODE;     return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, ®s, 0, NULL,NULL);}

 

 

进程0 

       所有进程的祖先叫做进程0,idle进程或因为历史的原因叫做swapper 进程。它是在linux的初始化阶段从无到有的创建的一个内核线程。这个祖先进程使用静态分配的数据结构。

      在多处理器系统中,每个CPU都有一个进程0,只要打开机器电源,计算机的BIOS就启动一个CPU,同时禁用其他CPU。运行的CPU 0上的swapper进程初初始化内核数据结构,然后激活其他的CPU,并且使用copy_process()函数创建另外的swapper进程,把0 传递给新创建的swapper进程作为他们进程的PID。

 

进程1 

      由进程0创建的内核线程执行init()函数,init() 一次完成内核的初始化。init()调用execve系统调用装入可执行程序init ,结果,init 内核线程变成一个普通的进程,且拥有自己的每个进程内核数据结构。在系统关闭之前,init 进程一直存活,因为它创建和监控在操作系统外层执行的所有进程的活动。

 

其他内核线程

      events 处理内核事件 很多软硬件事件(比如断电,文件变更)被转换为events,并分发给对相应事件感兴趣的线程进行响应

      ksoftirqd :处理软中断 硬件中断处理往往需要关中断,而这个时间不能太长,否则会丢失新的中断。所以中断处理的很大一部分工作移出,转给任劳任怨的ksoftirqd在中断之外进行处理。比如一个网络包,从网卡里面取出这个过程可能需要关中断,但是TCP/IP协议处理就不必关中断了

      kblockd :管理磁盘块读写

      kjournald: Ext3文件系统的日志管理 通常每个 _已mount_ 的 Ext3分区会有一个 kjournald看管,各分区的日志是独立

      Pdflush: dirty内存页面的回写 太多dirty的页面意味着风险,比如故障时候的内容丢失,以及对突发的大量物理内存请求的响应(大量回写会导致糟糕的响应时间)

 kswapd :内存回收 确保系统空闲物理内存的数量在一个合适的范围

      aio :代替用户进程管理io 用以支持用户态的AIO

驱动中应用内核线程

 

#include 
#include
#include
#include
#include
#include
#include
#include
static pid_t thread_id;staticDECLARE_COMPLETION(exit_completion);static atomic_t time_to_quit =ATOMIC_INIT(0); int my_fuction(void *arg){ int ret; daemonize("demo-thread"); allow_signal(SIGKILL); complete(&exit_completion); while(!signal_pending(current)){ printk("jiffies is %lu/n", jiffies); set_current_stat(TASK_INTERRUPTIBLE); schedule_timeout(10 * HZ); if(atomic_read(&kthread->terminate)) { /* we receiveda request to terminate ourself */ break; } } /* for(;;) { Ret = wait_event_interruptible(wq,condition); //可采用任何同步措施 }*/ complete_and_exit(&exit_completion,1); return0;}static int __init init(void){ thread_id = kernel_thread(my_fuction,NULL, CLONE_FS | CLONE_FILES); wait_for_completion(&exit_completion); return 0;}static void __exit finish(void){ atomic_inc(&time_to_quit); kill_proc(thread_id, SIGKILL, 1); wait_for_completion(&exit_completion); printk("Goodbye/n");}module_init(init);module_exit(finish);MODULE_LICENSE("GPL");

 

 

转载地址:http://nlivl.baihongyu.com/

你可能感兴趣的文章
ruby.taobao.org
查看>>
mysql 5.1 变量专题
查看>>
MyEclipse6.5下struts2+spring2+hibernate3 整合
查看>>
android中的JSON解析
查看>>
我的友情链接
查看>>
js模拟表单提交
查看>>
微信小程序开发简易计算器改进版
查看>>
混合背包问题
查看>>
Android studio树形
查看>>
hihoCoder1043
查看>>
【康托展开】
查看>>
6.19 docker (二)实战WordPresser
查看>>
关于mysql的初步学习 (三)
查看>>
html常用标签6-表单标签
查看>>
浅谈Java抽象类
查看>>
Codeforces Round #417 (Div. 2)
查看>>
vue-router history模式
查看>>
Python异步IO
查看>>
SQL 死锁进程查询
查看>>
linux下的时区修改
查看>>