进程管理

一切为了进程
进程是处于执行期的程序以及相关的资源的总称

进程的虚拟机制

  1. 虚拟处理器
    进程觉得自己在独享处理器
  2. 虚拟内存
    进程觉得自己在独享内存
    线程之间可以共享虚拟内存,但每个都拥有各自的虚拟处理器
    其实在linux中,线程和进程的区别不大,只是一种进程间共享资源的手段而已。线程和进程的创建都是调用clone实现的,只不过传入的参数不同而已。

进程生命周期相关的函数

fork() 他爹生他出来
复制一个现有的进程来创建一个全新的进程
exec() 他自己成家立业
为fork()的新进程读取可执行文件并将其载入地址空间开始运行
exit() 他死了
退出进程的执行并释放其占用的资源
wait() 他爹给它收尸

为什么unix要把创建一个进程拆分成fork和exec两部分?
我认为是为了进程的快速执行(我自己的理解)
利用写时拷贝技术。
当子进程的页根本不需要被写入的时候,无需复制
当子进程立马这些exec的时候,也无需复制
这样子进程就可以快速的执行啦

进程描述符

我认为,在linux中,任何一个“概念”都会有其对应的描述符
进程的描述符为struct task_struct,它能够完整的描述一个进程:进程打开的文件,进程的地址空间,挂起的信号,进程的状态等。

  • 系统中所有的进程描述符都存放在一个叫做任务队列(task_list)双向循环链表中。遍历整个任务队列:for_each_process(struct task_struct *task)
  • linux通过slab分配器分配task_struct,这样能达到对象复用和缓存着色的目的。(什么是缓存着色?)
  • 每个任务的 task_struct存放在它的内核栈的尾端(内核栈其他地方放的哪些?顺序是什么?) 通过current宏可以查找当前正在运行的进程的 task_struct

进程描述符的各个域

unsigned long state;//进程的当前状态(五种状态之一);

pid_t pid; //进程标识值,所有的进程都是pid为1的init进程的后代;

进程家族树:
children
parent

进程创建

fork() --> clone() -->do_fork() -->copy_process()
其中,clone()是系统调用

copy_process()函数的工作:

  1. 为新进程创建内核栈,thread_info和task_struct
  2. 修改一些必须和父进程不一样的属性
  3. 分配PID
  4. 根据clone传入的参数拷贝和共享一些东西比如进程地址空间等

进程终结

当一个进程死了(调用exit())之后要释放它占有的所有资源并且把这个消息告诉他的父进程,同时还要给他的儿子们找养父(从他所在的线程组中去找,找不到合适的话就托给init),最后等他爹来给他收尸埋掉(调用wait())才算完。

进程死了,只是他所占用的资源释放放了,但是他的进程描述符还在。这样做是为了让系统有办法在进程死了之后还能获得进程的信息,当系统确定了确实用不上之后,他的进程描述符才被释放掉

内核线程

内核线程是独立运行在内核空间的标准进程,与普通进程的区别在于它没有独立的地址空间(指向地址空间的mm指针被设置为NULL)。他们只在内核空间运行,不在用户空间运行。

注意内核线程创建不是用fork(),当然不能用fork啦,因为fork是库函数,内核不可以用库函数!

内核线程是由其他内核线程调用一下函数创建的,
kthread_create() //这个函数还是调用的clone()
kthread_run()
kthread_stop()

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值