Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1753180
  • 博文数量: 600
  • 博客积分: 10581
  • 博客等级: 上将
  • 技术积分: 6205
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-06 10:13
文章分类
文章存档

2016年(2)

2015年(9)

2014年(8)

2013年(5)

2012年(8)

2011年(36)

2010年(34)

2009年(451)

2008年(47)

分类: LINUX

2009-08-22 13:07:57

第三单元    进程管理

第一节 进程介绍

 

进程控制块PCB    (process control block)

PCB中包括进程的描述信息、控制信息以及资源信息、CPU现场等等。PCB反映一个进程的动态特性,它控制了各个进程之间的制约关系。

    一般情况下,在系统的PCB结构中,都包括了下列信息:

1)        进程描述信息。包括进程名称和标识、创建进程用户的用户名和标识、进程之间的

             层次关系。

2)        控制信息。包括了进程的状态信息优先级、程序地址、调度信息以及与其它进程的 通信状况。

进程在活动期间可以处于就绪状态、执行状态和阻塞状态。执行状态表示该进程占有处理机;就绪状态表示进程已经得到了除处理机以外所有的资源,等待处理机调度;阻塞状态是由于进程缺少某个必需的资源引起的,它等待其它进程释放资源再 继续运行。

3)        资源管理信息。包括存储器信息、使用的输入/输出设备信息、文件系统信息等等, 记录了系统占有的内存大小,共享内存段大小以及地址,输入/输出设备的设备号,设备缓冲区长度和地址。

4)         CPU现场。在系统运行过程中.处理器时间被划分为时间片,在每个时间片中执行 不同的进程,所以进程的执行不是一次完成的。在进行进程状态转换时.必须保存进程CPU现场的状态,以便下一次该进程被分配到时间片时,可以继续执行。 进程PCB块是系统控制进程的唯一途径。通过对PCB的操作,系统为进程分配调度所需要的资源,获取地址信息并保存进程状态转换时的环境。进程结束时,系统通过释放PCB块,就可以释放进程所占有的资源。

 

〓第二节 进程应用

fork( )

int fork()

 

int pid;

if((pid=fork())==0){

       /* child process. */

}else if (pid>0){

       /* 父进程*/

}else {

       fprintf(stderr,”fork process error \n”);

}

 

 

存储器分配

ANSI C说明了三个用于存储空间动态分配的函数。

(1) malloc。分配指定字节数的存储区。此存储区中的初始值不确定。

(2) calloc。为指定长度的对象,分配能容纳其指定个数的存储空间。该空间中的每一位

( b i t )都初始化为0

(3) realloc。更改以前分配区的长度(增加或减少)。当增加长度时,可能需将以前分配区的

内容移到另一个足够大的区域,而新增区域内的初始值则不确定。

 

[格式:]

#include

void *malloc(size_t  s i z e) ;

void *calloc(size_t         n o b j,   size_t     s i z e) ;

void *realloc(void   * p t r,    size_t     n e w s i z e) ;

 

三个函数返回:若成功则为非空指针,若出错则为N U L L

void free(void * p t r)

这三个分配函数所返回的指针一定是适当对齐的,使其可用于任何数据对象。例如,在一个特定的系统上,如果最苛刻的对齐要求是d o u b l e,则对齐必须在8的倍数的地址单元处,那么这三个函数返回的指针都应这样对齐。

 

!        EXAMPLE:

# include

# include

# include

 

void main(void)

{

   char * s;

   register int t;

   s=malloc(80);

  

   if(!s){

            printf(“memory request failed ..\n”);

            exit(1);

   }

   gets(s);

   for(t=strlen(s)-1;t>=0;t--)  putchar (s[t]);

   free(s);

}

 

getenv( )

环境字符串的形式是:

n a m e = v a l u e

U N I X内核并不关心这种字符串的意义,它们的解释完全取决于各个应用程序。例如,

s h e l l使用了大量的环境变量。其中某一些在登录时自动设置(如H O M EU S E R等),有些则由用户设置。我们通常在一个s h e l l起动文件中设置环境变量以控制s h e l l的动作。例如,若设置了环境变量M A I L PAT H,则它告诉Bourne shellK o r n S h e l l到哪里去查看邮件。

ANSI C定义了一个函数g e t e n v,可以用其取环境变量值,但是该标准又称环境的内容是由

实现定义的。

[格式:]

 

#include

 

char *getenv(const char * n a m e) ;

 

 

返回:指向与n a m e关联的v a l u e的指针,若未找到则为N U L L

 

注意,此函数返回一个指针,它指向n a m e = v a l u e字符串中的v a l u e。我们应当使用g e t e n v从环境中取一个环境变量的值,而不是直接存取e n v i r o n

 

!        EXAMPLE:

 

         short init_msgq()

{

                  char pathfil[40];

                  strcpy(pathfil,(char*)getenv("WORKDIR"));

                  strcat(pathfil,FILE_NAME);

        

                  return 0;

}

 

设置环境变量

[格式:]

 

#include

 

int putenv(const char * s t r) ;

int setenv(const char * n a m e, const char * v a l u e, int re w r i t e) ;

 

两个函数返回:若成功则为0,若出错则为非0

void unsetenv(const char * n a m e) ;

 

这三个函数的操作是:

• putenv取形式为n a m e = v a l u e的字符串,将其放到环境表中。如果n a m e已经存在,则先删除其原来的定义。

• setenvn a m e设置为v a l u e。如果在环境中n a m e已经存在,那么( a )re w r i t e0,则首先删除其现存的定义;( b )re w r i t e0,则不删除其现存定义(n a m e不设置为新的v a l u e,而且也不出错)。

• unsetenv删除n a m e的定义。即使不存在这种定义也不算出错。

这些函数在修改环境表时操作:

环境表(指向实际n a m e = v a l u e字符串的指针数组)和环境字符串典型地存放在进程存储空间的顶部(栈之上)。

删除一个字符串很简单——只要先找到该指针,然后将所有后续指针都向下移一个位置。但是增加一个字符串或修改一个现存的字符串就比较困难。栈以上的空间因为已处于进程存储空间的顶部,所以无法扩充,即无法向上扩充,也无法向下扩充。

 

 

(1) 如果修改一个现存的n a m e:

(a) 如果新v a l u e的长度少于或等于现存v a l u e的长度,则只要在原字符串所用空间中写入新字符串。

(b) 如果新v a l u e的长度大于原长度,则必须调用m a l l o c为新字符串分配空间,然后将新字符写入该空间中,然后使环境表中针对n a m e的指针指向新分配区。

 

(2) 如果要增加一个新的n a m e,则操作就更加复杂。首先,调用m a l l o cn a m e = v a l u e分配空间,然后将该字符串写入此空间中。

(a) 然后,如果这是第一次增加一个新n a m e,则必须调用m a l l o c为新的指针表分配空间。将原来的环境表复制到新分配区,并将指向新n a m e = v a l u e的指针存在该指针表的表尾,然后又将一个空指针存在其后。最后使e n v i r o n指向新指针表.如果原来的环境表位于栈顶之上(这是一种常见情况),那么必须将此表移至堆中。但是,此表中的大多数指针仍指向栈顶之上的各n a m e = v a l u e字符串。

(b) 如果这不是第一次增加一个新n a m e,则可知以前已调用m a l l o c在堆中为环境表分配

了空间,所以只要调用r e a l l o c,以分配比原空间多存放一个指针的空间。然后将该

指向新n a m e = v a l u e字符串的指针存放在该表表尾,后面跟着一个空指针。

 

 

阅读(579) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~