荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: zzt (好好学习,天天向上), 信区: Linux
标  题: 进程迁移技术及其发展(第四部分)
发信站: BBS 荔园晨风站 (Thu Feb 17 19:47:23 2000), 站内信件

发信人: xz (香紫), 信区: Linux
标  题: 进程迁移技术及其发展(第四部分)
发信站: 一网深情 (Thu Jul  1 06:57:55 1999), 转信

3.进程各类状态的保存和恢复
进程迁移的核心部分即进程各类状态的保存和恢复.本节就进程各类状
态,即正文段,数 据段,打开文件表,套接字地址,信号处理状态,CPU状
态,分别阐述其记录和恢复的实现方法.
3.1正文段
静态链接的UNIX进程在创建时,由核心将整个正文段装入虚地址空间,
通常是从地址0开始.而且,UNIX要求正文段必须以"只读"方式装入,因
此在运行过程中,正文段不会作任何修改.所以,对正文段不需作任何特
殊的保存,只需延用原可执行文件中的正文段即可.
3.2数据段
UNIX进程的数据段通常包括3个区域:初始化的数据,未初始化的数据
和堆.初始化及未初始化数据包括全局的和静态声明的变量,初始化数
据在编译时就按程序员给定的初值赋值,非初始化数据在编译时只计
算了需分配的空间,核心在装入数据时以零来填充.堆中的数据是运
行时由brk(),或sbrk()系统调用动态申请的,进程的数据段通常是从
紧邻着正文段之上的一个页边界开始的,而且是内存中的一段连续区
域.也就是说,初始化数据从正文段上第一个页边界开始,随后是非初
始化数据,然后是堆,在运行过程中堆会朝着高地址段生长. 数据段
是经常修改的内容之一,需要作记录和恢复的工作,才能保证进程从上
是经常修改的内容之一,需要作记录和恢复的工作,才能保证进程从上
一次中断的地方继续运行. 该模型下,在checkpoint阶段,将整个数
据段写入检查点文件中;在restart的阶段,在将其读入到相同的地址
空间.因此所需要的信息只是数据段的起始地址和结尾地址.
在Linux系统中,数据段的起始地址可以从进程的proc结构中查到.在
伪文件"/proc/PID/stat"中,可以读出进程的proc结构,取出数据段的
起始地址.
数据段的结尾地址,即堆的顶地址,可以通过UNIX系统调用shrk()得到.
在restart阶段,数据段的恢复安排在较早的阶段进行.
3.3栈
栈段是运行时分配的空间,用来存储函数调用机制所需的信息,函数调
用参数,自动变量及数组等.进程运行过程中栈段的大小随着函数的进
入和退出会发生变化.在某些UNIX系统中,栈段从进程虚地址空间中较
底部开始,朝着低地址方向生长.而另一些系统中,栈段从虚地址空间的
中部开始,为栈分配留出一定的空间,并朝着高地址方向生长.checkpoint
/restart的实现首先要了解栈的生长方向. 保存栈的状态需要保存两
部分各不相同的信息.首先,栈的上下文(stack context),有时也称为
栈环境(stack environment)必须进行保存.栈的上下文指与栈有关的
一些控制信息,其中最重要的是栈指针(stack pointer),栈指针指示
了进程运行在栈段的位置.其次,组成栈的实际数据,称为栈空间(stack
 space)也必须保存. 为保存和恢复栈的上下文,可利用ANSI C的函数
setjmp()和longjmp().setjmp()的调用参数是指向系统定义类型jmp_buf
的指针JMP_BUF.setjmp()将当前栈的上下文保存在JMP_BUF中,并返回
的指针JMP_BUF.setjmp()将当前栈的上下文保存在JMP_BUF中,并返回
零.如果longjmp()在其后被调用,其参数是JMP_BUF指针和一个非零值,
那么保存在JMP_BUF中的栈的上下文将恢复到当前运行环境中,进程的
运行则返回到调用setjmp()的代码处.这时,setjmp()的返回值将是longjmp()
调用参数所指定的非零值. 但是,setjmp()/longjmp()调用的局限在于,
JMP_BUF中并不包含栈空间本身的内容,只包括指向栈空间的指针.而当
restart时,新进程已有了自己的栈段,因此在checkpoint阶段,需要另外
保存栈空间的实际内容.在restart阶段,需要以检查点文件中的栈空间
来取代新进程的栈空间,然后再利用longjmp()调用来恢复原先的栈上下
文. 将栈空间的内容记录到检查点文件很简单,只要知道栈段的起始和
结尾地址. 在Linux系统中,栈向低地址方向生长,在checkpoint阶段,
可以从伪文件"/proc/PID/stat"中读出栈的高地址端的偏移量,栈的低
地址端即栈指针所指的值,可以通过调用setjmp()然后从JMP_BUF中读出
栈指针的值.最后,将栈的低地址端到高地址端的一段内容记入检查点文件.
在restart阶段,栈的恢复需要一点技巧,不能象恢复数据段那样立刻就恢
复栈段.因为在替换栈段时仍需要用到运行栈.直接替换在检查点文件中
保存的栈空间,必然会使进程的运行发生不可知的错误.为避免出现这样
的错误,需要先将栈指针转移到进程数据段中一段安全的缓冲栈之中.

--
※ 来源:.一网深情 bbs.uestc.edu.cn.[FROM: 202.202.37.26]

--
☆ 来源:.BBS 荔园晨风站 bbs.szu.edu.cn.[FROM: bbs@192.168.1.11]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店