操作系统实验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);
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)