进程管理
3.1进程
1.进程:进程就是处于执行期的程序,实际上,进程就是正在执行的程序代码的实时结果;
2.执行线程,简称线程,是进程中活动的对象(每个线程拥有独立的程序计数器、进程栈、和一组进程寄存器),内核调度的对象是线程,不是进程
3.进程提供的两种虚拟进制:虚拟处理器和虚拟内存
4.程序本身不是进程
5.调用fork(),该系统调用通过复制一个现有进程来创建一个全新的进程;接这调用exce()函数,可以创建新的地址空间,并把程序载入其中;最后,程序通过exit()系统调用退出调用。这个函数会终结进程并将其占用的资源释放掉
*fork()实际上是由clone()系统调用实现的
3.2进程描述符及任务结构
1.双向循环链表中,每一项都是类型为task_struct,称为进程描述符的结构;该结构定义在<sched.h>文件中
2.进程描述符中包含的数据能完整地描述一个正在执行的程序
3.每个任务的thread_info结构在它的内核栈的尾端分配。结构中task域中存放的是指向该任务实际的task_struct的指针
4.进程描述符的PID的最大值实际就是系统中允许同时存在的进程的最大数目;
5.进程描述符中的state域描述了进程的当前状态;必然处于五个状态的一种:
task_running
task_interruprtion
task_uninterruption
task_traced
task_stopped
*调整某个进程的状态,这时使用set_task_state函数:
6.进程只有通过这些接口才能陷入内核执行——对内核的所有访问都必须通过这些接口
系统中的每个进程必有一个父进程,相应的,每个进程也可以拥有零个或者多个子进程。拥有同一个父进程的所有进程被称为兄弟。进程间的关系存放在进程描述符中
3.3进程创建
1.首先,fork()通过拷贝当前进程创建一个子进程。子进程与父进程的区别仅仅在于PID、PPID和某些资源的统计量;exec()函数负责读取可执行文件并将其载入地址空间开始运行;
2.linux通过clone()系统调用实现fork();do_fork完成创建中的大部分工作,定义在kernel/fork.c文件中
3.除了不拷贝父进程的页表项外,vfork()系统调用和fork功能相同;vfork()系统调用的实现是通过向clone()系统调用传递一个特殊标志来进行的
3.4线程在linux中的实现
1.创建线程:与普通进程的创建类似,只不过调用clone()时候需要传递一些参数标志来指明需要共享的资源,参数标志决定了新创建进程的行为方式和父子进程之间共享的资源种类
2.内核线程和普通的进程间的区别在于内核线程没有独立的地址空间,它们只在内核空间进行,从来不切换到用户空间。内核进程和普通进程一样,可以被调度,也可以被抢占
3.kthread内核进程通过clone()系统调用而创建。新的进程将运行threadfn函数,传递的参数为data
3.5进程终结
1.在调用do_exit()之后,尽管线程已经僵死不能再运行,但是系统还是保留了它的进程描述符。
2.wait()这一组函数通过唯一的一个系统调用wait4()来实现
3.linux如何存放(task_struct)和表示进程(thread_info);创建(fork());,实际上最终clone()