----原文链接:http://www.cnblogs.com/biyeymyhjob/archive/2012/08/01/2617884.html------

Linux进程通过一个task_struct结构体描述,在linux/sched.h中定义,通过理解该结构,可更清楚的理解linux进程模型。       包含进程所有信息的task_struct数据结构是比较庞大的,但是该数据结构本身并不复杂,我们将它的所有域按其功能可做如下划分:

  • 进程状态(State)
  • 进程调度信息(Scheduling Information)
  • 各种标识符(Identifiers)
  • 进程通信有关信息(IPC:Inter_Process Communication)
  • 时间和定时器信息(Times and Timers)
  • 进程链接信息(Links)
  • 文件系统信息(File System)
  • 虚拟内存信息(Virtual Memory)
  • 页面管理信息(page)
  • 对称多处理器(SMP)信息
  • 和处理器相关的环境(上下文)信息(Processor Specific Context)
  • 其它信息

1. 进程状态(State)

进程执行时,它会根据具体情况改变状态。进程状态是调度和对换的依据。Linux中的进程主要有如下状态,如表1所示。

表3.1  Linux进程的状态

内核表示

含义

TASK_RUNNING

可运行

TASK_INTERRUPTIBLE

可中断的等待状态

TASK_UNINTERRUPTIBLE

不可中断的等待状态

TASK_ZOMBIE

僵死

TASK_STOPPED

暂停

TASK_SWAPPING

换入/换出

1).可运行状态:处于这种状态的进程,要么正在运行、要么正准备运行。正在运行的进程就是当前进程(由current所指向的进程),而准备运行的进程只要得到CPU就可以立即投入运行,CPU是这些进程唯一等待的系统资源。

2).等待状态:处于该状态的进程正在等待某个事件(event)或某个资源,它肯定位于系统中的某个等待队列(wait_queue)中。

3).暂停状态:此时的进程暂时停止运行来接受某种特殊处理。通常当进程接收到SIGSTOP、SIGTSTP、SIGTTIN或 SIGTTOU信号后就处于这种状态。例如,正接受调试的进程就处于这种状态。

4).僵死状态:进程虽然已经终止,但由于某种原因,父进程还没有执行wait()系统调用,终止进程的信息也还没有回收。顾名思义,处于该状态的进程就是死进程,这种进程实际上是系统中的垃圾,必须进行相应处理以释放其占用的资源。

进程状态转换如下图:

2.进程调度信息

调度程序利用这部分信息决定系统中哪个进程最应该运行,并结合进程的状态信息保证系统运转的公平和高效。这一部分信息通常包括进程的类别(普通进程还是实时进程)、进程的优先级等。表2描述了跟进程调度有关的字段,表3.3说明了几种常用的进程调度算法及这些算法的使用范围,如先来先服务主要用于实时进程的调度。

表2 进程调度信息

域名

含义

need_resched

调度标志

Nice

静态优先级

Counter

动态优先级

Policy

调度策略

rt_priority

实时优先级

表3  进程调度的策略

名称

解释

适用范围

SCHED_OTHER

其他调度

普通进程

SCHED_FIFO

先来先服务调度

实时进程

SCHED_RR

时间片轮转调度

只有root用户能通过sched_setscheduler()系统调用来改变调度策略。

3.标识符(Identifiers)

每个进程有进程标识符、用户标识符、组标识符,如表4所示。

不管对内核还是普通用户来说,怎么用一种简单的方式识别不同的进程呢?这就引入了进程标识符(PID:process identifier),每个进程都有一个唯一的标识符,内核通过这个标识符来识别不同的进程,同时,进程标识符PID也是内核提供给用户程序的接口,用户程序通过PID对进程发号施令。PID是32位的无符号整数,它被顺序编号:新创建进程的PID通常是前一个进程的PID加1。然而,为了与16位硬件平台的传统Linux系统保持兼容,在Linux上允许的最大PID号是32767,当内核在系统中创建第32768个进程时,就必须重新开始使用已闲置的PID号。

表4 各种标识符

域名

含义

Pid

进程标识符

Uid、gid

用户标识符、组标识符

Euid、egid

有效用户标识符、有效组标识符

Suid、sgid

备份用户标识符、备份组标识符

Fsuid、fsgid

文件系统用户标识符、文件系统组标识符

4.进程通信有关信息(IPC:Inter_Process Communication)

为了使进程能在同一项任务上协调工作,进程之间必须能进行通信即交流数据。

Linux支持多种不同形式的通信机制。它支持典型的Unix 通信机制(IPC Mechanisms):信号(Signals)、管道(Pipes),也支持System V 通信机制:共享内存(Shared Memory)、信号量和消息队列(Message Queues),如表5

表5 进程通信有关信息

域名

含义

Spinlock_t sigmask_lock

信号掩码的自旋锁

Long blocked

信号掩码

Struct signal  *sig

信号处理函数

Struct sem_undo *semundo

为避免死锁而在信号量上设置的取消操作

Struct sem_queue *semsleeping

与信号量操作相关的等待队列

5.进程链接信息(Links)

程序创建的进程具有父/子关系。因为一个进程能创建几个子进程,而子进程之间有兄弟关系,在task_struct结构中有几个域来表示这种关系。

在Linux系统中,除了初始化进程init,其他进程都有一个父进程(parent process)或称为双亲进程。可以通过fork()或clone()系统调用来创建子进程,除了进程标识符(PID)等必要的信息外,子进程的task_struct结构中的绝大部分的信息都是从父进程中拷贝,或说“克隆”过来的。系统有必要记录这种“亲属”关系,使进程之间的协作更加方便,例如父进程给子进程发送杀死(kill)信号、父子进程通信等,就可以用这种关系很方便地实现。

每个进程的task_struct结构有许多指针,通过这些指针,系统中所有进程的task_struct结构就构成了一棵进程树,这棵进程树的根就是初始化进程init的task_struct结构(init进程是Linux内核建立起来后人为创建的一个进程,是所有进程的祖先进程)。表6是进程所有的链接信息。

表6 进程链接信息

名称

解释 [指向哪个进程]

p_opptr

祖先

p_pptr

父进程

p_cptr

子进程

p_ysptr

弟进程

p_osptr

兄进程

Pidhash_next、

Pidhash_pprev

进程在哈希表中的链接

Next_task、

prev_task

进程在双向循环链表中的链接

Run_list

运行队列的链表

6.时间和定时器信息(Times and Timers)

一个进程从创建到终止叫做该进程的生存期(lifetime)。进程在其生存期内使用CPU的时间,内核都要进行记录,以便进行统计、计费等有关操作。进程耗费CPU的时间由两部分组成:一是在用户模式(或称为用户态)下耗费的时间、一是在系统模式(或称为系统态)下耗费的时间。每个时钟滴答,也就是每个时钟中断,内核都要更新当前进程耗费CPU的时间信息。

表7是和时间有关的域,上面所说的counter是指进程剩余的CPU时间片,也和时间有关,所以这里我们再次提及它。表8是进程的所有定时器。

表7与时间有关的域

域名

含义

Start_time

进程创建时间

Per_cpu_utime

进程在某个CPU上运行时在用户态下耗费的时间

Per_cpu_stime

进程在某个CPU上运行时在系统态下耗费的时间

Counter

进程剩余的时间片

表8  进程的所有定时器

定时器类型

解释

什么时候更新

用来表示此种定时器的域

ITIMER_REAL

实时定时器

实时更新,即不论该进程是否运行

it_real_value

it_real_incr

real_timer

ITIMER_VIRTUAL

虚拟定时器

只在进程运行于用户态时更新

it_virt_value

it_virt_incr

ITIMER_PROF

概况定时器

进程运行于用户态和系统态时更新

it_prof_value

it_prof_incr

7.文件系统信息(File System)

进程可以打开或关闭文件,文件属于系统资源,Linux内核要对进程使用文件的情况进行记录。task_struct结构中有两个数据结构用于描述进程与文件相关的信息。其中,fs_struct中描述了两个VFS索引节点(VFS inode),这两个索引节点叫做root和pwd,分别指向进程的可执行映象所对应的根目录(home directory)和当前目录或工作目录。file_struct结构用来记录了进程打开的文件的描述符(descriptor)。如表9所示。

表9  与文件系统相关的域

定义形式

解释

Sruct fs_struct *fs

进程的可执行映象所在的文件系统

Struct files_struct *files

进程打开的文件

在文件系统中,每个VFS索引节点唯一描述一个文件或目录,同时该节点也是向更低层的文件系统提供的统一的接口。

8.虚拟内存信息(Virtual Memory)

除了内核线程(kernel thread),每个进程都拥有自己的地址空间(也叫虚拟空间),用mm_struct来描述。另外Linux2.4还引入了另外一个域active_mm,这是为内核线程而引入。因为内核线程没有自己的地址空间,为了让内核线程与普通进程具有统一的上下文切换方式,当内核线程进行上下文切换时,让切换进来的线程的active_mm指向刚被调度出去的进程的active_mm(如果进程的mm域不为空,则其active_mm域与mm域相同)。内存信息如表10所示

表10   虚拟内存描述信息

定义形式

解释

Struct mm_struct *mm

描述进程的地址空间

Struct mm_struct *active_mm

内核线程所借用的地址空间

9.页面管理信息

当物理内存不足时,Linux内存管理子系统需要把内存中的部分页面交换到外存,其交换是以页为单位的。有关页面的描述信息如表11。

表11 页面管理信息

定义形式

解释

Int swappable

进程占用的内存页面是否可换出

Unsigned long min_flat,

maj_flt,nswap

进程累计的次(minor)缺页次数、

主(major)次数及累计换出、换入页面数

Unsigned long cmin_flat,

cmaj_flt,cnswap

本进程作为祖先进程,其所有层次子进程的累计的次(minor)缺页次数、主(major)次数及累计换出、换入页面数

10.进程内核栈及current宏

在Linux-2.6内核中堆栈这么定义:

union thread_union
{
    struct thread_info thread_info;
    unsigned long stack[THREAD_SIZE/sizeof(long)];
};

根据内核的配置,THREAD_SIZE既可以是4K字节(1个页面)也可以是8K字节(2个页面)。thread_info是52个字节长。下图是当设为8KB时候的内核堆栈:Thread_info在这个内存区的开始处,内核堆栈从末端向下增长。进程描述符不是在这个内存区中,而分别通过task与thread_info指针使thread_info与进程描述符互联。所以获得当前进程描述符的current定义如下:

#define current get_current()
static inline struct task_struct * get_current(void)
{
    return current_thread_info()->task;
}
static inline struct thread_info *current_thread_info(void)
{
    struct thread_info *ti;
    __asm__("andl %%esp,%0; ":"=r" (ti) : "" (~(THREAD_SIZE - 1)));
    return ti;
}

根据THREAD_SIZE大小,分别屏蔽掉内核栈的12-bit LSB(4K)或13-bit LSB(8K),从而获得内核栈的起始位置,及当前进程描述符的指针。

Linux进程模型的更多相关文章

  1. linux进程模型总结

    Linux进程通过一个task_struct结构体描述,在linux/sched.h中定义,通过理解该结构,可更清楚的理解linux进程模型.       包含进程所有信息的task_struct数据 ...

  2. Linux进程/内核模型

    内核必须实现一组服务和相应的接口,应用程序则可以使用这些接口,而不是直接与硬件打交道. Linux内核主要由以下5个子系统组成:进程调度.内存管理.虚拟文件系统.进程间通信以及设备驱动. 在这个组成中 ...

  3. linux C++ 通讯架构(一)nginx安装、目录、进程模型

    nginx是C语言开发的,号称并发处理百万级别的TCP连接,稳定,热部署(运行时升级),高度模块化设计,可以用C++开发. 一.安装和目录 1.1 前提 epoll,linux内核版本为2.6或以上 ...

  4. 第一次作业:基于Linux 4.5的进程模型与调度器分析

    1.操作系统是怎么组织进程的? 1.1什么是线程,什么是进程: 刚接触时可能经常会将这两个东西搞混.简单一点的说,进程是一个大工程,线程则是这个大工程中每个小地方需要做的东西(在linux下看作&qu ...

  5. Linux IO模型和网络编程模型

    术语概念描述: IO有内存IO.网络IO和磁盘IO三种,通常我们说的IO指的是后两者. 阻塞和非阻塞,是函数/方法的实现方式,即在数据就绪之前是立刻返回还是等待. 以文件IO为例,一个IO读过程是文件 ...

  6. Linux 进程

    Linux 进程 在用户空间,进程是由进程标识符(PID)表示的.从用户的角度来看,一个 PID 是一个数字值,可惟一标识一个进程.一个 PID 在进程的整个生命期间不会更改,但 PID 可以在进程销 ...

  7. Server Develop (五) Linux并发模型

    Linux并发模型 目前可以实现并发程序的方法有Apache模型(Process Per Connection,简称PPC),TPC(Thread PerConnection)模型,以及select模 ...

  8. Linux设备模型(总线、设备、驱动程序和类)

    Linux设备驱动程序学习(13) -Linux设备模型(总线.设备.驱动程序和类)[转] 文章的例子和实验使用<LDD3>所配的lddbus模块(稍作修改). 提示:在学习这部分内容是一 ...

  9. 探索 Linux 内存模型--转

    引用:http://www.ibm.com/developerworks/cn/linux/l-memmod/index.html 理解 Linux 使用的内存模型是从更大程度上掌握 Linux 设计 ...

随机推荐

  1. JDK、JRE和JVM的关系

    JDK中包含了JRE,JRE中包含了JVM. 详解: JDK是JAVA的核心,包括JRE(JAVA 虚拟环境).编译器等,JDK的主流产品是由SUN公司开发的,JDK本身是用JAVA编写的,安装包的S ...

  2. Ajax PHP JavaScript MySQL实现简易的无刷新在线聊天室

    思路 消息显示区 发消息 板块 消息显示 消息发送 优化 显示非重复性的数据 优化显示 加上滚动条 每次都显示最新消息 完整代码 前端代码 数据库表结构 服务器端代码 总结与展望 总结 展望 为更好的 ...

  3. java自动装箱拆箱总结

    对于java1.5引入的自动装箱拆箱,之前只是知道一点点,最近在看一篇博客时发现自己对自动装箱拆箱这个特性了解的太少了,所以今天研究了下这个特性.以下是结合测试代码进行的总结. 测试代码: int a ...

  4. Unity3D核心技术详解

    在这里将多年游戏研发经验的积累写成一本书奉献给读者,目前已经开始预售,网址: http://www.broadview.com.cn/article/70 该书主要是将游戏中经常使用的技术给大家做了一 ...

  5. Spark分布式计算和RDD模型研究

    1背景介绍 现今分布式计算框架像MapReduce和Dryad都提供了高层次的原语,使用户不用操心任务分发和错误容忍,非常容易地编写出并行计算程序.然而这些框架都缺乏对分布式内存的抽象和支持,使其在某 ...

  6. Dynamics CRM2016 业务流程之Task Flow(二)

    接上篇,Page页设置完后,按照业务流程管理也可以继续设置Insert page after branch 或者 Add branch,我这里选择后者,并设置了条件,如果Pipeline Phase ...

  7. Anakia 转换xml文档为其他格式

    一.简介 Anakia 使用JDOM 和Velocity将XML文档转换为特定格式的文档 二.解析xml文档方法 1.DOM java jdk,xml-api.jar 需要加载整个xml文档来构建层次 ...

  8. 关于React Native 安卓首屏白屏优化

    问题描述 在android中,当点击某个rn模块的入口按钮,弹出rn的activity到rn的页面展现出来的过程中,会有很明显的白屏现象,不同的机型不同(cpu好的白屏时间短),大概1s到2s的时间. ...

  9. Servlet之异常处理

    当一个 Servlet 抛出一个异常时,Web 容器在使用了exception-type 元素的 web.xml 中搜索与抛出异常类型相匹配的配置. 前提是必须在 web.xml 中使用 error- ...

  10. MonoBehaviour介绍(Unity3D开发之一)

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: http://www.cocos2dev.com/?p=486 猴子自学Unity已经一段 ...