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进程数据结构详解的更多相关文章

  1. linux进程地址空间详解(转载)

    linux进程地址空间详解(转载) 在前面的<对一个程序在内存中的分析 >中很好的描述了程序在内存中的布局,这里对这个结果做些总结和实验验证.下面以Linux为例(实验结果显示window ...

  2. Linux进程退出详解(do_exit)--Linux进程的管理与调度(十四)

    Linux进程的退出 linux下进程退出的方式 正常退出 从main函数返回return 调用exit 调用_exit 异常退出 调用abort 由信号终止 _exit, exit和_Exit的区别 ...

  3. linux进程控制函数详解

    进程控制 fork函数 创建一个子进程. pid_t fork(void); 失败返回-1:成功返回:① 父进程返回子进程的ID(非负) ②子进程返回 0 pid_t类型表示进程ID,但为了表示-1, ...

  4. Linux进程管理详解

    何谓进程?进程,就是正在执行的一个程序或命令,每一个进程都是一个运行实体,有自己的地址空间,并占用一定的系统资源.简而言之,进程就是运行中的程序.在Linux中,诸如ls等命令都是进程,只不过某些命令 ...

  5. Linux /dev目录详解和Linux系统各个目录的作用

    Linux /dev目录详解(转http://blog.csdn.net/maopig/article/details/7195048) 在linux下,/dev目录是很重要的,各种设备都在下面.下面 ...

  6. linux select函数详解

    linux select函数详解 在Linux中,我们可以使用select函数实现I/O端口的复用,传递给 select函数的参数会告诉内核: •我们所关心的文件描述符 •对每个描述符,我们所关心的状 ...

  7. 红帽Linux故障定位技术详解与实例(2)

    红帽Linux故障定位技术详解与实例(2) 2011-09-28 14:26 圈儿 BEAREYES.COM 我要评论(0) 字号:T | T 在线故障定位就是在故障发生时, 故障所处的操作系统环境仍 ...

  8. Linux启动过程详解(inittab、rc.sysinit、rcX.d、rc.local)

    启动第一步--加载BIOS 当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的重要,以至于计算机必须在最开始就找到它.这是因为BIOS中包含了CPU的相关信息.设备启动顺序信息.硬 ...

  9. Linux启动过程详解

    Linux启动过程详解 附上两张图,加深记忆 图1: 图2: 第一张图比较简洁明了,下面对第一张图的步骤进行详解: 加载BIOS 当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的 ...

随机推荐

  1. 信号值大于-75dBm时

    dBm是一个表示功率绝对值的值,是以1mw为0dbm,公式dbm=10×lg(毫瓦数/1).所以,为负值 这个值越大,表示信号越好,如-70dbm信号比-90dbm好  信号值大于-75dBm时,说明 ...

  2. elasticsearch安装与使用(5)-- search guard安装与配置

    一.安装search guard插件必须要安装两部分: ①search-guard-xx ②search-guard-ssl (XX指的是与elasticsearch引擎对应的版本) github地址 ...

  3. 责任链模式 - tomcat

    class filterChain{ private List<Filter> filters; public void addFilter(Filter filter){ filters ...

  4. CodeIgniter(3.1.4)框架-url重写,去除index.php

    1.开启Apache重写url模块. *相应内容可百度. 2.在项目根目录下创建[.htaccess]文件,其内容如下: RewriteEngine On RewriteCond %{REQUEST_ ...

  5. Arrays.sort和Collections.sort实现原理解析

    Arrays.sort和Collections.sort实现原理解析 1.使用 排序 2.原理 事实上Collections.sort方法底层就是调用的array.sort方法,而且不论是Collec ...

  6. Hbase建模

    转自:http://blog.itpub.net/28912557/viewspace-1119865/ 什么情况下使用Hbase?1,成熟的数据分析主题,查询模式已经确定并且不易轻易改变.(主要还是 ...

  7. Spring 依赖注入(DI)的注解

    Spring中想要使用注解进行依赖注入,需要进行如下配置: <beans xmlns="http://www.springframework.org/schema/beans" ...

  8. 如果分配给命令的连接位于本地挂起事务中,ExecuteNonQuery 要求命令拥有事务。命令的 Transaction 属性尚未初始化

    DbConnection dbc = database.CreateConnection(); DbTransaction dbtt = null; try { dbc.Open(); dbtt = ...

  9. 在windows下编译x264

    最近因为各种原因,对流媒体的学习,突然中断在了编码这块.今天难得静下心来,从新拿起了代码. 对encode这边,因为之前虽然也接触了,也找了两个例子,但目前还没真正开始,所以先从编译x264这个库开始 ...

  10. 3D游戏与计算机图形学中的数学方法-视截体

    视截体用来表示一个空间的范围,位于这个空间范围内的三维场景的任何物体都可以被看到. 视截体由六个平面围成,其中的四个平面与场景的边界相对应,分别被称为左,右,底,顶视截面.另外两个平面称为近视截面和远 ...