Linux进程数据结构详解
1、Linux的进程简介:
支持多线程的操作系统中,进程是资源分配的最小单位,线程是调度的基本单位。Linux是现代的32位或64位的支持多线程的操作系统,不过Linux是一种以轻量级进程作为线程,多线程任务中的数个线程以线程的组的方式存在,每个线程以轻量级进程实现。
Linux的轻量级进程没有独立的内存空间,进程有独立的内存空间,其中内核级轻量级进程没有内存空间,用户级轻量级进程共享内存空间,进程有自己的mm_struct。
事实上你可以如下理解:linux下,轻量级进程就是指线程,符合POSIX标准规范。至于创建一个线程的细节,你可以参考关于clone这个函数的介绍,除了用clone实现轻量级进程,实际上fork也是调用clone来实现的。
2、Linux进程的描述的数据结构
Linux中的进程以及轻量级进程(以下简称为线程)使用同样的描述符数据结构task_struct(可以在一定程度上理解为PCB)。
task_struct的数据成员主要有:进程状态、内核栈信息、进程使用状态、PID、优先级、锁、时间片、队列、信号量、内存管理信息、文件列表等等与进程管理、调度密切相关的信息。
详细源码参照:内核3.0.6_task_struct源码.txt文件
3、Linux的进程的组织结构、状态以及转换
Linux中,进程的组织结构是双向链表的形式,task中有prev和next的指针,其中链表表头head的位置是0号进程或者说是swapper进程的task_struct。SET_LINKS 和 REMOVE_LINKS 宏分别用于从进程链表中插入和删除一个进程描述符。这些宏考虑了进程间的父子关系。,
进程状态转换图:
◆运行状态(TASK_RUNNING)
当进程正在被CPU执行,或已经准备就绪随时可由调度程序执行,则称该进程为处于运行状态(running)。进程可以在内核态运行,也可以在用户态运行。当系统资源已经可用时,进程就被唤醒而进入准备运行状态,该状态称为就绪态。这些状态(图中中间一列)在内核中表示方法相同,都被成为处于TASK_RUNNING状态。
◆可中断睡眠状态(TASK_INTERRUPTIBLE)
当进程处于可中断等待状态时,系统不会调度该进程执行。当系统产生一个中断或者释放了进程正在等待的资源,或者进程收到一个信号,都可以唤醒进程转换到就绪状态(运行状态)。
◆不可中断睡眠状态(TASK_UNINTERRUPTIBLE)
与可中断睡眠状态类似。但处于该状态的进程只有被使用wake_up()函数明确唤醒时才能转换到可运行的就绪状态。
◆暂停状态(TASK_STOPPED)
当进程收到信号SIGSTOP、SIGTSTP、SIGTTIN或SIGTTOU时就会进入暂停状态。可向其发送SIGCONT信号让进程转换到可运行状态。在Linux 0.11中,还未实现对该状态的转换处理。处于该状态的进程将被作为进程终止来处理。
◆僵死状态(TASK_ZOMBIE)
当进程已停止运行,但其父进程还没有询问其状态时,则称该进程处于僵死状态。
当一个进程的运行时间片用完,系统就会使用调度程序强制切换到其它的进程去执行。另外,如果进程在内核态执行时需要等待系统的某个资源,此时该进程就会调用sleep_on()或sleep_on_interruptible()自愿地放弃CPU的使用权,而让调度程序去执行其它进程。进程则进入睡眠状态(TASK_UNINTERRUPTIBLE或TASK_INTERRUPTIBLE)。
只有当进程从“内核运行态”转移到“睡眠状态”时,内核才会进行进程切换操作。在内核态下运行的进程不能被其它进程抢占,而且一个进程不能改变另一个进程的状态。为了避免进程切换时造成内核数据错误,内核在执行临界区代码时会禁止一切中断。
4、0号进程的秘密
传说中的swapper进程,其描述符是提前设计好的,进程0创建时,系统设置了时钟,便于进程的调度轮询,process0,以下简称p0。p0具备处理系统调用,这需要通过set_system_gate和system_call(系统调用的总入口)与IDT挂接。
此外,p0还需要与task[64]、GDT、LDT、TSS挂接,并把优先级由0调整为3。Linux规定所有进程(p0除外)必须有其他进程在3特权级别下创建。因而p0需要调用move_to_user_mode()进行优先级翻转。
优先级翻转在响应中断时完成,在响应中断时,系统的各个寄存器的数据按顺序压栈(SS、ESP、EFLAGS、CS、EIP),恢复时按照反序出栈,在相应中断过程中,set_system_gate就是设置int 0x80中断,由3级(iret)反转到0级(iret),同理也可以由0级(iret)翻转到3级(iret)。注:
0级:执行系统代码
3级:执行进程代码
0号进程不是由3级翻转到0级的,没有预先的压栈数据,所以要手工模拟压栈,表示该属性的ss字段的后两位必须是11(3),总值:0x17。
5、1号与2号进程
1号进程由0号进程创建,2号进程由1好进程创建。
2号进程的执行,将意味着shell开始执行,boot过程结束,设备实现怠速。
创建进程过程:
(1)调用fork()函数:
将相应的信息压栈:以便于调用copy_process后初始化p1的TSS。压栈:fork函数偏移值(2)赋给eax,SS、ESP、EFLAGS、CS、EIP入栈,然后DS、ES、FS、EDX、ECX、EBX入栈。
(2)开始执行fork()
在task[64]除[0]以外的数组项初始化清空,调用下面的函数:find_empty_process()获得一个PID和数组中的一个位置。接下来在父进程的内核中继续压栈,5个寄存器的值入栈,为调用copy_process()做准备。
(3)调用copy_process()
创建子进程的task_struct;
复制父进程的task_struct信息到子进程的task_struct之中;
为子进程做struct和tss的个性化设置;
创建子进程的页表,复制父进程页表项到子进程;
共享文件;
设置GDT,将子进程的状态设置为就绪;
注:task_struct和内核栈共同构成task_union:正好占据一页。
Linux进程数据结构详解的更多相关文章
- linux进程地址空间详解(转载)
linux进程地址空间详解(转载) 在前面的<对一个程序在内存中的分析 >中很好的描述了程序在内存中的布局,这里对这个结果做些总结和实验验证.下面以Linux为例(实验结果显示window ...
- Linux进程退出详解(do_exit)--Linux进程的管理与调度(十四)
Linux进程的退出 linux下进程退出的方式 正常退出 从main函数返回return 调用exit 调用_exit 异常退出 调用abort 由信号终止 _exit, exit和_Exit的区别 ...
- linux进程控制函数详解
进程控制 fork函数 创建一个子进程. pid_t fork(void); 失败返回-1:成功返回:① 父进程返回子进程的ID(非负) ②子进程返回 0 pid_t类型表示进程ID,但为了表示-1, ...
- Linux进程管理详解
何谓进程?进程,就是正在执行的一个程序或命令,每一个进程都是一个运行实体,有自己的地址空间,并占用一定的系统资源.简而言之,进程就是运行中的程序.在Linux中,诸如ls等命令都是进程,只不过某些命令 ...
- Linux /dev目录详解和Linux系统各个目录的作用
Linux /dev目录详解(转http://blog.csdn.net/maopig/article/details/7195048) 在linux下,/dev目录是很重要的,各种设备都在下面.下面 ...
- linux select函数详解
linux select函数详解 在Linux中,我们可以使用select函数实现I/O端口的复用,传递给 select函数的参数会告诉内核: •我们所关心的文件描述符 •对每个描述符,我们所关心的状 ...
- 红帽Linux故障定位技术详解与实例(2)
红帽Linux故障定位技术详解与实例(2) 2011-09-28 14:26 圈儿 BEAREYES.COM 我要评论(0) 字号:T | T 在线故障定位就是在故障发生时, 故障所处的操作系统环境仍 ...
- Linux启动过程详解(inittab、rc.sysinit、rcX.d、rc.local)
启动第一步--加载BIOS 当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的重要,以至于计算机必须在最开始就找到它.这是因为BIOS中包含了CPU的相关信息.设备启动顺序信息.硬 ...
- Linux启动过程详解
Linux启动过程详解 附上两张图,加深记忆 图1: 图2: 第一张图比较简洁明了,下面对第一张图的步骤进行详解: 加载BIOS 当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的 ...
随机推荐
- 向大家推荐一个C/C++通用Makefile
在使用 Makefile 之前,只需对它进行一些简单的设置即可:而且一经设置,即使以后对源程序文件有所增减一般也不再需要改动 Makefile.因此,即便是一个没有学习过 Makefile 书写规则的 ...
- Storm学习笔记——高级篇
1. Storm程序的并发机制 1.1 概念 Workers (JVMs): 在一个物理节点上可以运行一个或多个独立的JVM 进程.一个Topology可以包含一个或多个worker(并行的跑在不同的 ...
- vmware克隆Centos6.4虚拟机网卡无法启动问题
vmware克隆Centos6.4虚拟机网卡无法启动问题 2014-02-26 16:44:54 标签:老男孩培训 vmware克隆问题 网卡无法启动 ...
- 关于BETA、RC、ALPHA、Release、GA等版本号的意义
关于BETA.RC.ALPHA.Release.GA等版本号的意义 转载 2016年06月19日 00:04:00 2049 0 1 . 最近由于工作需要经常要去SVN上拉开源项目的源码,对项目 ...
- iOS边练边学--view的封装
一.view封装的思路: *如果一个view内部的子控件比较多,一般会考虑自定义一个view,把它内部的子控件的创建屏蔽起来,不让外界关心 *外界可以传入对应的模型数据给view,view拿到模型数据 ...
- Java-ThreadLocal,Java中特殊的线程绑定机制
在DRP项目中,我们使用了ThreadLocal来创建Connection连接,避免了一直以参数的形式将Connection向下传递(传递connection的目的是由于jdbc事务要求确保使用同一个 ...
- 一个CSS3滤镜Drop-shadow阴影效果
<html> <head> <title>CSS3 Drop-shadow阴影</title> <style type="text/cs ...
- smo算法matlab实现
看完CSDN上结构之法,算法之道的支持向量机通俗导论(理解SVM的三层境界) http://blog.csdn.net/v_july_v/article/details/7624837 参考了 ...
- R语言低级绘图函数-text
text函数用来在一张图表上添加文字,只需要指定对应的x和y坐标,以及需要添加的文字内容就可以了 基本用法: plot(1:5, 1:5, xlim = c(0,6), ylim = c (0,6), ...
- CentOS Linux 下安装Samba
一.Samba简介: Samba是在Linux和UNIX系统上实现SMB协议的一个免费软件,由服务器及客户端程序构成.Linux中搭建环境有几个需要使用的软件包: (1)samba-client:这个 ...