操作系统实验2

Linux进程的软中断通信与管道通信

1)软中断通信

编制一段程序并适当加以注释,实现软中断通信:在系统中调用signal()让父进程捕捉键盘上来的Ctrl+C中断信号实现父进程中断;父进程调用fork()函数创建两个子进程,休眠10秒钟后,父进程调用kill()函数向两个子进程分别发送整数值为17和17的软中断信号,各子进程获得对应信号后,分别输出下列信息后终止:
Child process 1 is killed by parent !
Child process 2 is killed by parent !
父进程再调用wait()函数等待两个子进程终止后,输出以下信息后终止:
Parent process is killed!!
多运行几次编写的程序,简略分析出现不同结果的原因。

代码如下

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
int wait_flag;
void stop();

main(){
	int pid1,pid2;
	signal(SIGINT,stop);
	while((pid1=fork())==-1);/*创建子进程pid1*/ 

	if(pid1>0){ /* 子进程pid代码*/ 
        printf("\n I am the parent process,my pid is:  %d \n",getpid());//输出父进程 
		while((pid2=fork())==-1);//创建子进程pid 2成功 
		if(pid2>0){/*子进程pid1代码*/ 
			wait_flag=1;
            printf("\n I am sleeping for 10s\n");
			sleep(10);/*子进程pid1休眠10S  */ 
			kill(pid1,17);//向子进程pid 1 发出信号17 
			kill(pid2,17);//向子进程pid 2 发出信号17 
			int kpid1=wait(0);//等待pid1 的子进程 pid 2的结束符号 
            printf("\n child process has ended %d \n",kpid1);
			int kpid2=wait(0);
            printf("\n child process has ended  %d \n",kpid2);
			printf("\n Parent process is killed!!\n");
			exit(0);
		}
		else{/*子进程 */ 
            printf("\n I am the child process2,my pid is:%d\n",getpid());
			wait_flag=1;
			signal(17,stop);//如接收到信号17,则执行stop函数 
            while(1){
            	/*若执行了stop 函数,wait_flag会变成 0,则子进程结束*/ 
			   if(wait_flag==0){
                  printf("\n Child process2 is killed by parent!!\n");
			      exit(0);
               }
            }
		}
	}
	else{
        printf("\n I am the child process1,my pid is:%d\n",getpid());
		wait_flag=1;
		signal(17,stop);//如接收到信号17,则执行stop函数 
        while(1){
        	/*若执行了stop 函数,wait_flag会变成 0,则子进程结束*/ 
            if(wait_flag==0){
               printf("\n Child process1 is killed by parent!!\n");
               exit(0);
            }
        }
	}
}

void stop(){//信号执行句柄函数 
    printf("\n stop() is called\n"); 
	wait_flag=0;//若执行此函数,可以让全局变量wait_flag的值变为0 
}

运行后截图:

2)管道通信

编制一段程序并适当加以注释,实现进程的管道通信: 使用系统调用pipe()建立一条管道线,两个子进程分别向管道各写一句话:
Child process 1 is sending a message!
Child process 2 is sending a message!
而父进程则从管道中读出来自于两个子进程的信息,显示在屏幕上。

代码如下:

#include<unistd.h>
#include<signal.h>
#include<stdio.h>
int pid1,pid2;

main(){
	int fd[2];
	char OutPipe[100],InPipe[100];
	pipe(fd);//创建管道 
	while((pid1=fork())==-1);//创建子进程pid 1 成功 
	if(pid1==0){ //子进程pid1 
		lockf(fd[1],1,0);//上锁,只允许pid1 向管道中写入 
		sprintf(OutPipe,"\n Child process1 is sending message! \n");
		write(fd[1],OutPipe,50);//从管道的写入端讲50个数据写入管道 
		sleep(5);//延时5秒 
		lockf(fd[1],0,0);//解锁 
		exit(0);//子进程结束 
	}
	else{
		while((pid2=fork())==-1);//创建子进程pid 2成功 
		if(pid2==0){//子进程pid2 ,基本同上 
			lockf(fd[1],1,0);
			sprintf(OutPipe,"\n Child process2 is sending message! \n");
			write(fd[1],OutPipe,50);
			sleep(5);
			lockf(fd[1],0,0);
			exit(0);//子进程结束 
		}
		else{//父进程 
			wait(0);//等待子进程执行完毕 
			read(fd[0],InPipe,50);//从管道的读出端读出50个数据 
			printf("%s\n",InPipe);
			wait(0);//等待子进程执行完毕 
			read(fd[0],InPipe,50);
			printf("%s\n",InPipe);
			exit(0);
		}
	}
}

运行结果截图:

posted @   星星盛开的地方  阅读(457)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示