1、操作系统实验4实验四 进程治理-进程的互斥及信号通信一目的和要求(1)进一步熟悉进程并发执行的实质,明白得进程的同步、互斥、撤消等操纵方式;(2)熟悉进程间通过软中断信号传递操纵信息的方式(低级通信)二实验内容一、编写一段程序,实现软中断通信: 利用系统挪用fork( )创建两个子进程,父进程用系统挪用kill()向两个子进程别离发送整数值为SIGUSR1和SIGUSR2软中断信号,子进程取得对应软中断信号后,别离输出以下信息后终止: Child process 1 is killed by parent ! Child process 2 is killed by parent ! 父进程挪
2、用wait( )函数等待两个子进程终止后,输出以下信息后终止: Parent process is killed! 多运行几回编写的程序,简略分析显现不同结果的缘故。 二、编写一段程序,实现进程互斥。 运行下面的程序,观看程序的执行结果:#include main() int i,p1,p2; while(p1=fork()= =-1); /*父进程创建第一个子进程,直到成功*/ if(p1= =0) /*0返回给子进程p1*/ for(i=0;i5;i+) /*p1的处置进程*/ printf(“Child1 %dn”,i); else /*正数返回给父进程(即子进程号)*/ while(p
3、2=fork()= =-1); /*父进程创建第二个子进程,直到成功*/ if(p2= =0) /*0返回给子进程p2*/ for(i=0;i5;i+) /*p2的处置进程*/ printf(“Child2 %dn”,i); else for(i=0;i5;i+) /*p2创建完成后,父进程的处置进程*/ printf(“Parent %dn”,i); 多次运行程序,观看运行结果。将上述代码中的三处for(i=0;i5;i+)改成for(i=0;i0时,核心将信号发送给进程pid。(2)pid=0时,核心将信号发送给与发送进程同组的所有进程。(3)pid=-1时,核心将信号发送给所有效户标识符
4、真正等于发送进程的有效用户标识号的进程。在命令提示符下利用kill l 能够查看有哪些信号。关于这些信号的详细说明请查看命令man 7 signal的输出结果。信号事件的发生有两个来源:一个是硬件的缘故(比如按下了某个键),一个是软件的缘故(比如利用系统函数或命令发出信号)。五、signal( )预置对信号的处置方式,许诺挪用进程操纵软中断信号。收到信号的进程对各类信号有不同的处置方式。处置方式能够分为三类:第一种是类似中断的处置程序,关于需要处置的信号,进程能够指定处置函数,由该函数来处置。第二种方式是,忽略某个信号,对该信号不做任何处置,就象未发生过一样。第三种方式是,对该信号的处置保留系
5、统的默许值,这种缺省操作,对大部份的信号的缺省操作是使进程终止。进程通过系统挪用signal( )来指定进程对某个信号的处置行为。本系统挪用的头文件为:#include 系统挪用格式:signal(sig,function)int sig;void (*function) ( )其中sig用于指定信号的类型,sig为0那么表示没有收到任何信号。sig的值是以下之一: SIGHUP 挂起 1SIGINT 键盘按Ctrl-c键或Ctrl-break键 2SIGQUIT 键盘按quit键(Ctrl-) 3SIGILL 非法指令 4SIGTRAP 跟踪中断 5SIGIOT/SIGABRT IOT指令或
6、挪用abort函数生成的信号 6SIGBUS 总线错 7SIGFPE 浮点运算溢出 8SIGKLL 要求终止进程 9SIGUSR1 用户概念信号#1 10SIGSEGV 段违法 11SIGUSR2 用户概念信号#2 12SIGPIPE 向无读者管道上写 13SIGALRM 按时器告警,时刻到 14SIGTERM kill发出的软件终止信号 15SIGCHLD 子进程死 17SIGPWR 电源故障 30function是该进程中的一个函数地址,function 的说明如下:(1)function=1时,进程对sig类信号不予理会,亦即屏蔽了该类信号;(2)function=0时,缺省值,进程在收
7、到sig信号后应终止自己;(3)function为非0、非1整数时,function的值即作为信号处置程序的指针。function还能够是:(1)SIG_IGN 忽略那个信号.(2)SIG_DFL 恢复对那个信号的默许处置有关系统挪用signal( )的例子:例1():#include #include #include main( )signal(SIGINT,SIG_IGN); /*忽略那个信号*/printf(”hello!n”);sleep(10);printf(”world”);例2():#include #include #include int catch(int sig);ma
8、in()signal(SIGINT,catch);printf(”hello!n”);sleep(10);printf(”worldn”);int catch(int sig)printf(”catch signal.n”);例3:()下面程序的功能:对Ctrl-c组合键的响应是输出一条消息而不是终止运行;程序将在用户第二次按下Ctrl-c组合键后终止。#include #include #include void ouch(int sig) printf(I got signal %dn,sig); signal(SIGINT,SIG_DFL); /*恢复对那个信号的默许处置*/int ma
9、in() signal(SIGINT,ouch); while(1) printf(Hello World! n); sleep(1); 请运行上面程序并分析运行结果。(提示:当用户通过按下Ctrl-c组合键给出SIGINT信号时,函数ouch将被挪用,程序会在函数ouch终止后继续执行,但信号处置动作恢复为默许动作,当程序接收到第二个SIGINT信号时,程序采纳默许动作,终止执行。)例4:通过编译:gcc o signaltest0取得可执行文件:signaltest0后台执行该文件:(在文件名后面加上 &)/*或者写成:kill -9 1586*/*向进程发送SIGHUP信号*/*向进程发
10、送SIGINT信号*/*向进程发送SIGQUIT信号*/前台执行该文件:/*或者写成:kill -9 1612*/*按Ctrl+C组合键得到的结果*/*按Ctrl+ 组合键得到的结果*/*按Ctrl+Z组合键得到的结果*/六、raise( ) raise( )系统挪用用于向自身发送信号。本系统挪用的头文件为:#include 系统挪用格式:int raise(int sig);挪用成功时返回0,犯错时返回-1。能够看出,raise( )能够通过kill( )实现,raise(sig)等价于kill(getpid( ),sig);7、alarm( )alarm( )系统挪用的功能是设置一个按时器
11、,当按时器计时抵达时,将发出信号SIGALRM给进程。若是不忽略或捕捉此信号, 它的默许操作是终止挪用该alarm函数的进程。本系统挪用的头文件为:#include 系统挪用格式:unsigned int alarm(unsigned int seconds);若是参数seconds为0,那么之前设置的闹钟会被取消,并将剩下的时刻(剩余的秒数)返回,若是之前未设置闹钟,那么返回0。注意:在利历时,alarm( )只设置为发送一次信号,若是要多次发送,就要多次挪用alarm( )函数。八、pause( )pause( )系统挪用的功能是使当前进程暂停,进入眠眠状态,直到被信号所中断。本系统挪用的
12、头文件为:#include 系统挪用格式:int pause(void);该函数只返回-1。程序范例:编译并运行该程序,若是去掉代码中的signal( )函数挪用,结果是什么?四、参考程序:参考程序1:#include #include #include #include int wait_mark;void waiting();void stop(int sig);main() int p1,p2; while(p1=fork()=-1); if (p10) /*父进程的处置*/ while(p2=fork()=-1); if (p20) /*父进程的处置*/ wait_mark=1; ge
13、tchar(); kill(p1,SIGUSR1); /*向子进程p1发出信号SIGUSR1*/ kill(p2,SIGUSR2); /*向子进程p2发出信号SIGUSR2*/ wait(0); /*同步*/ wait(0); printf(Parent process is killed!n); exit(0); else /*子进程p2的处置*/ wait_mark=1; signal(SIGUSR2,stop); waiting(); /*等待信号SIGUSR2*/ sleep(1); lockf(int)stdout,1,0); /*用上锁的方式实现互斥*/ printf(Child
14、process 2 is killed by parent!n); lockf(int)stdout,0,0); /*模拟子进程P2被kill时进程的工作*/ exit(0); else /*子进程p1的处置*/ wait_mark=1; signal(SIGUSR1,stop); waiting(); /*等待信号SIGUSR1*/ sleep(1); lockf(int)stdout,1,0); /*用上锁的方式实现互斥*/ printf(Child process 1 is killed by parent!n); lockf(int)stdout,0,0); /*模拟子进程P1被kil
15、l时进程的工作*/ exit(0); void waiting() while(wait_mark!=0);void stop(int sig) printf(I got signal %dn,sig); wait_mark=0;运行程序,观看运行结果,并分析。参考程序2:#include #include #include main() int p1,p2,i; FILE *fp; fp=fopen(,w); /*以写的方式打开文件*/ if(fp=NULL) printf(Fail to create file); exit(-1); while(p1=fork()=-1); /*创建子进
16、程p1*/ if(p1=0) lockf(int)fp,1,0); /*加锁*/ for(i=0;i1000;i+) fprintf(fp,Child1 %dn,i); lockf(int)fp,0,0); /*解锁*/ else while(p2=fork()=-1); /*创建子进程p2*/ if(p2=0) lockf(int)fp,1,0); /*加锁*/ for(i=0;i1000;i+) fprintf(fp,Child2 %dn,i); lockf(int)fp,0,0); /*解锁*/ else wait(0); wait(0); lockf(int)fp,1,0); /*加锁*/ for(i=0;i1000;i+) fprintf(fp,Parent %dn,i); lockf(int)fp,0,0); /*解锁*/ fclose(fp); /*关闭文件*/ 四试探题在本实验中,进程的同步和互斥是如何实现的?
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2