操作系统实验教程(5)

2018-12-17 15:09

if (fork()==0) { …;

execl(…); …; }

wait(&status);

4.wait( )

等待子进程运行结束。如果子进程没有完成,父进程一直等待。wait()将调用进程挂起,直至其子进程因暂停或终止而法来软中断信号为止。如果在wait()前已有子进程暂停或终止,则调用进程作适当处理后便返回。 系统调用格式:

int wait(status)int *status; 5.exit( )

终止进程的执行。 系统调用格式: void exit(status) int status;

其中,status是返回给父进程的一个整数,0表示正常结束,其他的数值表示出现了错误。

为了及时回收进程所占用的资源并减少父进程的干预,UNIX/Linux利用exit( )来实现进程的自我终止,通常父进程在创建子进程时,应在进程的末尾安排一条exit(),使子进程自我终止。exit(0)表示进程正常终止,exit(1)表示进程运行有错,异常终止。 6.lockf(files,function,size)

用作锁定文件的某些段或整个文件。 本函数的头文件为:#include “unistd.h” 系统调用格式:

int lockf(files,function,size) int files,function; long size;

19

其中,file是文件描述符;function是锁定和解锁:1 表示锁定,0 表示解锁。size是锁定或解锁的字节数,为0,表示从文档的当前位置到文件尾。 7.getpid()

本函数的头文件为: #include #include

功能:用来得到进程唯一的pid号。 格式: pid-t getpid(void)

3.2 程序实例

例:编写一段程序,利用系统调用fork( )创建两个进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”;子进程分别显示字符“b”和字符“c”。

#include main() {

int p1,p2;

while ((p1=fork())= =-1); if (p1= =0) putchar(?b?); else {

while ((p2=fork()= =-1); if (p2= =0)

putchar(?c?); else

putchar(?a?);

} }

分析:从进程并发执行来看,输出bac,acb或bca都有可能。

原因:fork()创建进程所需要的时间要多于输出一个字符的时间,因此在主进程创建进程2的同时,进程1就输出了”b”,而进程2和主程序的输出次序是有随机性的,所以会出现多种可能结果。

例:修改已经编号的程序,将每个进程输出一个字符改为每个进程输出一句话,

20

在观察程序执行时屏幕上出现的现象,并分析原因。

如果在程序中使用系统调用lockf()来给每一个进程加锁,可以实现进程之间的互斥,观察并分析出现的现象。 参考程序1:

#include main() {

int p1,p2;

while ((p1=fork()= =-1); if (p1= =0)

for(i=0;i<50;i++)

printf(“child%d\\n”,i); else {

while ((p2=fork()= =-1); if (p2= =0)

for(i=0;i<50;i++)

printf(“son%d\\n”,i); else

for(i=0;i<50;i++)

printf(“daughter%d\\n”,i);

} }

运行结果: child… son…

daughter…

或 child

…son …child …son

…daughter 等

分析:由于函数printf()输出的字符串之间不会被中断,因此,字符串内部的字符顺序输出时不变。但是,由于进程并发执行时的调度顺序和父子进程的抢占处理机问题,处处字符串的顺序和先后随着执行的不同而发生变化。 参考程序2:

#include

#include main()

21

{

int p1,p2,I;

while ((p1=fork()= =-1); if (p1= =0) {

lockf(1,1,0); for(i=0;i<50;i++) printf(“child%d\\n”,i); lockf(1,0,0);

} else {

while ((p2=fork()= =-1); if (p2= =0) {

lockf(1,1,0); for(i=0;i<50;i++) printf(?son%d\\n”,i); lockf(1,0,0);

} else {

lockf(1,1,0); for(i=0;i<50;i++)

printf(“daughter%d\\n”,i); lockf(1,0,0); } } }

实验四 进程通信

4.1父子进程同步

在linux系统中,系统调用wait()和exit()是进程同步的主要手段。执行

exit可以终止进程的执行,使调用他的进程进入等待善后处理状态,并等待父进程对终止的子进程进行善后处理。因此在用户态程序中,可以调用fork产生子进程,当子进程希望终止时,可以调用exit。在父进程中可以使用wait等待其子进程终止。

父进程等待子进程终止:

22

系统调用wait对处于等待善后处理状态的子进程进行善后处理。父进程调用wait(status)等待它的一个子进程终止。

如果调用wait()之前,已有一个子进程结束了,则父进程对其善后处理后返回。

如果调用wait()的进程没有子进程,返回-1。

如果调用wait()时它的子进程还没有终止,则进入阻塞状态。 #include #include #include #include main() {

pid_t pc,pr; pc=fork(); if(pc<0)

printf(“error occurred!\\n”); else if(pc= =0) {

printf(“This is child process with pid of %d\\n”,getpid()); sleep(10);

} else {

pr=wait(NULL);

printf(“I catched a child process with pid of %d\\n”,pr); } exit(0); }

23


操作系统实验教程(5).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:2013白蒲中学高一数学教案:函数:27

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: