进程(一)操作系统原理及Linux进程源语

来源:互联网 发布:手机淘宝删除不了评价 编辑:程序博客网 时间:2024/05/27 06:50

这部分有点乱,先说下进程的状态,然后是一些概念,最后是Linux中的一些特别的进程和源语。

 

进程的状态
一般上进程有四种状态就绪(ready)、执行(running)、阻塞(blocked)、挂起(suspend)状态。

1)就绪状态
进程获得了除CPU以外的所有资源,系统中可能存在多个就绪状态的进程,通常将它们组成一个队列称为就绪队列。

2)执行状态
进程在执行的过程中总要涉及用户程序和操作系统内核程序两部分,因此进程的执行状态又可进一步分为用户执行状态和系统执行状态,区分用户态和系统态的主要原因是想把用户程序和系统程序分开,以利于程序的保护和共享。

3)阻塞状态
正在执行的进程由于发生某个事件而暂时无法继续执行下去,如进程申请的内存无法得到满足或申请I/O设备而设备正忙等,此时进程只能放弃CPU而进入暂停状态,即进程的执行受到了阻塞,把这种暂停状态称为阻塞状态(也称等待状态)。根据进程阻塞的原因(如等待IO、等待内存)可以将处于阻塞状态的进程排成若干个序列,当事件发生(设备释放IO)后,可从对应的阻塞队列上释放一个进程进入就绪状态。

4)挂起状态
按照一定的算法将内存中处于阻塞状态的进程暂时交换到外存(对应于挂起操作Suspend),并插入到响应的挂起队列中,从而空出内存以调入位于外存挂起队列中将要运行的进程(对应激活操作Active),实现虚拟存储管理功能。线程没有挂起状态,不会因为交换而进入外存。下面为进程各个状态之间转换关系。

 

进程的组成及PCB
一个进程一般由进程控制块(Process Control Block, PCB)、有关程序段和相应的数据结构(堆栈、数据等)组成。系统根据进程的PCB而感知进程的存在,并通过PCB控制、管理进程,PCB是进程存在的唯一标志。系统创建一个新进程的过程就是为相应的程序建立一个PCB的过程。进程运行结束,系统就回收其PCB,进程也随之消亡。

进程空间
任何进程都有一个自己的生存地址空间,该空间就是进程空间或虚空间(就是txt、data、堆栈等段存在的地址空间),为了确保系统安全可靠,Linux将进程空间分成用户空间和系统空间(32位情况下每个进程都有自己的虚拟的3G用户空间,而剩下的1G的系统空间是所有进程共享的)。而且为了防止用户空间访问系统空间的对系统造成破坏,操作系统将寄存器状态设置成不同的运行模式,即用户模式和系统模式来限制用户进程对系统资源的访问。系统模式下,可以运行系统的所有指令,访问所有的寄存器和内存区,而用户模式下就有所限制。

进程的上下文
程序计数器、寄存器、程序状态字、堆栈内容等是进程控制的主要依据,它们反映了进程执行的当前情况一起系统变化的数据,称之为处理机上下文。当进程切换的时候相应的PCB、处理机上下文都要发生变化,所以进程的切换对应于上下文的切换。

 

 

Linux中的进程和源语

1.关于进程占用的资源

大体可分两类,一类是进程所占的文件描述符和所占的存储空间,都是在进程退出前由内核自动释放的。还有就是进程结束后还有一部分资源和信息需要通知进程的父进程(每个进程都有父进程),包括进程号,进程的终止状态(正常还是不正常,异常的话是什么异常)和进程使用的CPU总量。

2.关于fork()和exec()

fork是产生子进程,如果不调用exec那么所用的堆栈空间和数据空间是父进程的拷贝。如果在fork中调用exec函数的话,是用一个全新的程序替换了当前进程的堆栈,数据空间和正文的内容。在网络服务器上会用到fork比较多,父进程接受请求,接收到请求产生一个子进程完成请求,可能是为了隔离开各个进程的空间和安全方面的考虑,用多进程的方式。

Linux启动时系统运行于核心态,此时仅仅创建一个pid号为0的idle进程,该进程会创建一个内核线程,该线程进行一系列的初始化动作后最终会执行init文件,文件init运行的结果是使得系统的运行模式从系统态到用户态,然后该进程演变为用户进程init其pid为1.此init进程是一个非常重要的进程,以后系统中的一切进程都是他的后代。init可以通过fork创建新的进程,当进程执行完毕的时候进程调用exit()终止自己,当进程撤销时,一方面要回收进程所占的资源同时要通知其父进程。exit()代码在kernel/exit.c中,其主要函数为do_exit(),do_exit()先释放进程的大部分资源,然后进入task_ZOMBIE状态,并调用exit_notify()通知父进程和子进程。

3.关于init进程

这个进程可以是很多进程的父进程,当一个进程结束的时候,操作系统会访问所有的进程,看看进程是不是这个结束进程的子进程,如果是就把这个进程的父进程设置成init进程(pid=1),(ps命令查看init的父进程号是0,但是史蒂文森说可以把init的父进程看成它本身)。init进程还有一点特殊的,当它的一个子进程结束后,它立刻的调用wait函数接受子进程返回的信息,回收剩余的资源,防止产生僵尸进程。

4.关于僵尸进程

如果一个进程结束,但是这个进程的父进程没有调用wait函数来做善后处理(获取信息,释放资源),那么这个进程就是僵尸进程(这个进程已经结束,但是还是占用着进程号)。如果一个进程一直运行或者一个进程要运行很长时间,而且要产生子进程的话,那么就可能产生很多的僵尸进程。

5.关于进程的退出

分正常和异常两种情况。正常的情况下基本是exit()和_exit()两个函数,exit()会执行一些处理函数(终止处理程序,使用atexit(void (*fun)(void))添加),类似于析构函数,并且清理IO。_exit()不执行这些函数,是否清理IO看不同操作系统的实现。

原创粉丝点击