操作系统(实验2)软中断和管道通信
1.小知识(本篇没用到)
按^c键 就是按 ctrl+c
2.软中断通信
#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); //创建子进程
//控制权交到父进程
if(pid1>0){
printf("\n I am the parent process,my pid is: %d \n",getpid());
while((pid2=fork())==-1); //创建子进程
if(pid2>0){ //控制权交到父进程
wait_flag=1;
printf("\n I am sleeping for 10s\n");
sleep(10); //父进程等待10s
kill(pid1,17); //向子进程1发出信号17
kill(pid2,17);//向子进程2发出信号17
int kpid1=wait(0); //等待子进程1的结束信号
printf("\n child process has ended %d \n",kpid1);
int kpid2=wait(0);//等待子进程2的结束信号
printf("\n child process has ended %d \n",kpid2);
printf("\n Parent process is killed!!\n");
exit(0);
}
else{//以下是子进程2的代码
printf("\n I am the child process2,my pid is:%d\n",getpid());
wait_flag=1;
signal(17,stop);//若接收到信号17执行stop函数
while(1){//循环等待
if(wait_flag==0){
printf("\n Child process2 is killed by parent!!\n");
exit(0);
}
}
}
}
else{//以下是子进程1的代码
printf("\n I am the child process1,my pid is:%d\n",getpid());
wait_flag=1;
signal(17,stop);//若接收到信号17执行stop函数
while(1){//循环等待
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变为1
}
运行结果:
I am the parent process,my pid is : 13214
I am the child process1,my pid is :13215
I am sleeping for 10s
I am the child process1,my pid is :13216
stop() is called
stop() is called
Child process2 is killed by parent!!
Child process1 is killed by parent!!
child process has ended 13215
child process has ended 13216
parent process is killed!!
3.管道通信
#include<unistd.h>
#include<signal.h>
#include<stdio.h>
int pid1,pid2;
main(){
int fd[2];
char OutPipe[100],InPipe[100];//暂存读出,或要写入的字符串
pipe(fd); //创建管道 ,fd[0]用于管道的读取端,fd[1]用于管道的写入端
while((pid1=fork())==-1);//创建子进程1
if(pid1==0){//以下是子进程1的代码
lockf(fd[1],1,0);//此处,为管道的写入端,加锁,从当前偏移量到文件结尾区域
sprintf(OutPipe,"\n Child process1 is sending message! \n");//把串放入数组outpipe中
write(fd[1],OutPipe,50);//向管道写长为50字节的串
sleep(5);//子进程1等待5s
lockf(fd[1],0,0); //此处,为管道的写入端,解锁
exit(0);//子进程1退出,结束
}
else{
while((pid2=fork())==-1);//创建子进程2
if(pid2==0){ //以下是子进程2的代码
lockf(fd[1],1,0);//此处,为管道的写入端,加锁 互斥
sprintf(OutPipe,"\n Child process2 is sending message! \n");//把串放入数组outpipe中
write(fd[1],OutPipe,50);//向管道写长为50字节的串
sleep(5);//子进程2等待5s
lockf(fd[1],0,0); //此处,为管道的写入端,解锁
exit(0);//子进程2退出,结束
}
else{//以下是父进程代码
wait(0);//阻塞,等待子进程1的结束信号
read(fd[0],InPipe,50);//从管道中读取长为50字节的串
printf("%s\n",InPipe);
wait(0);//阻塞,等待子进程1的结束信号
read(fd[0],InPipe,50);//从管道中读取长为50字节的串
printf("%s\n",InPipe);
exit(0);
}
}
}
运行结果:
child process 1 is sending message!
child process 2 is sending message!
4.总结和心得体会
(1)软中断通信:了解了基本知识,硬中断,操作系统系统外设状态的变化。为了满足实时系统的要求,中断处理应该是越快越好。linux为了实现这个特点,当中断发生的时候,硬中断处理那些短时间就可以完成的工作,而将那些处理事件比较长的工作,放到中断之后来完成,也就是软中断来完成。基本的思路是: 父进程生成子进程,父进程发送信号并等待,子进程接收信号,然后自我终止并唤醒父进程,父进程再自我终止。
(2)管道通信: 基本思路:可以实现父进程创建2个子进程,为了用wait()实现2个子进程先向管道里写入信息,然后父进程再读取。子进程1被创建后,获得管道资源,对其进行加锁,然后向管道里写入数据,之后解锁释放管道资源和cpu,之后父进程wait()操作。则子进程2获得管道资源,也写入信息,然后父进程读出信息。
通过本次实验我了解了软中断通信和管道通信进一步认识到了并发的实质,对Linux进程管理有了更多的认识,学会了一些函数的应用,但是这只是很小一部分,我还需要课下多查阅资料,加强和巩固自己的学习。