zoukankan      html  css  js  c++  java
  • 操作系统第3次实验报告:管道

    0.个人信息

    • 姓名 罗廷杨
    • 学号 201821121013
    • 班级 计算1811

    1. 编写程序

    在服务器上用Vim编写程序:创建一个命名管道,创建两个进程分别对管道进行读fifo_read.c和写fifo_write.c。源代码如下:

    1.fifo_write.c

    #include<stdio.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<string.h>
    #include<fcntl.h>
    #include<errno.h>
    #include<signal.h>
    #define MAX 128
    #define FIFO "./fifo"
    
    //写端
     void delSignal(int sig){
          printf("读端已经关闭!!SIGPIPE的信号值为%d
    ",sig);
         exit(-1);
     }
    
     int main(){
     
         //读端直接关闭,写端写完数据就会发送这个信号终止进程
         signal(SIGPIPE,delSignal);
         //建立自命名管道
         if(mkfifo(FIFO, 0640) == -1)
         {
             if(errno != EEXIST)//如果错误类型是fifo类型文件已经存在那么继续执行
             {
                 perror("mkfifo");
                 exit(-1);
             }
         }
          char buff[MAX];
          int fw=open(FIFO,O_WRONLY);//以只写的形式打开有名管道文件fifo
          if(fw==-1){//fifo文件打开失败
              printf("自命名管道文件打开失败!!!
    ");
              exit(-1);
          }
          //fifo文件打开成功
          printf("请输入要写入管道的内容(输入##结束)
    ");
         while(1){
              memset(buff, 0, sizeof(buff));
              fgets(buff,MAX,stdin);//获取用户输入一行的值
              if(strcmp(buff,"##
    ")==0){//判断是否结束写入
                  break;
              }
              write(fw,buff,strlen(buff));//将用户输入的值将写入fifo
          }
          close(fw);
          return 0;
      }

    2.fifo_read.c

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<unistd.h>
    #include<fcntl.h>
    #include<errno.h>
    #define MAX 128
    #define FIFO "./fifo"
    //读端
     int main(){
    
         if(mkfifo(FIFO, 0640) == -1)
          {
              if(errno != EEXIST)//如果错误类型是fifo类型文件已经存在那么继续执行
               {
                   perror("mkfifo");
                   exit(-1);
              }
           }
    
    
         char buff[MAX]={0};
         int count=0;
         int fr=open(FIFO,O_RDONLY);//以只读的形式打开有名管道文件fifo
         if(fr==-1){//fifo文件打开失败
             printf("自命名管道文件打开失败!!!
    ");
             exit(-1);
         }
         //fifo文件打开成功
         printf("从管道中读取的内容为
    ");
         while(read(fr,buff,MAX)!=0){//写入端还未关闭
             count++;
             printf("第%d次读取的内容:%s",count,buff);//取出写入端写入fifo中的内容
             memset(buff, 0, sizeof(buff));
         }
         printf("写文件端已经关闭!!!
    ");
         close(fr);
         return 0;
    }

    2. 分析运行结果

    1.正常执行情况下的运行结果

    ./write的运行结果

     ./read的运行结果

    当运行./write和./read但是还没有往管道里面写入数据时,./write和./read都会先处于阻塞状态,我们可以观察到两个程序都没有继续运行。当在./write程序中输入数据,这时./write程序就会往管道内写入数据,数据写入完成后就会被./read程序检测到,然后将数据读出显示到控制台中。当往./write中输入##那么写程序就结束执行,这样一来./read程序就无法在管道内读取到数据,因此也结束执行。

    2../write强制退出的运行结果

    ./write的运行结果

    ./read的运行结果

     

    ./write程序强制退出,也就是说没有程序往管道中写入数据了,那么./read就无法从管道中读取数据因此也随之结束运行。

    3../read强制退出的运行结果

    ./read的运行结果

    ./write的运行结果

     

     当./read程序强制退出之后,./write程序再往管道中写入数据那么就会产生异常,继而产生信号--SIGPIPE(13)来结束运行。

    说明

    创建命名管道的方式有两种,一种是在程序中创建,另一种是直接在命令行中创建。

    1.在程序中创建

    使用函数  int mkfifo(const char *filename, mode_t mode);

    其中mode(管道模式)有如下几种:

      O_RDONLY:读管道。

      O_WRONLY:写管道。

      O_RDWR:读写管道。

      O_NONBLOCK:非阻塞。

      O_CREAT:如果该文件不存在,就创建一个新的文件,并使用第3个参数为其设置权限。

      O_EXCL:测试文件是否存在。

    2.使用命令行创建

    mkfifo  filename

    3. 通过该实验产生新的疑问及解答

    疑问:signal(SIGPIPE,delSignal);的处理过程是什么样子的?

    解答:signal是一个带signum和handler两个参数的函数,需要处理的信号由参数signum给出,接收到指定信号时将要调用的函数由handler给出,此处signum对应于SIGPIPE,handler对应于delSignal。./write程序执行过程中,当./read进程结束信号没有发生时,./write进程正常运行,当信号发生时,./write进程的正常运行会被中断,然后去处理SIGPIPE信号,一看需要处理的信号是SIGPINE,就会从“信号处理方式登记表”中找到对应的信号处理函数,此处是delSignal函数,然后取出该函数的地址并执行该函数,从而打印出相应的提示信息并结束./write进程。

    参考文献

    【1】https://blog.csdn.net/qq_39755395/article/details/78568953

    【2】https://www.cnblogs.com/zhanggaofeng/p/6075725.html

  • 相关阅读:
    [EF]vs15+ef6+mysql code first方式
    Asp.net MVC]Asp.net MVC5系列——布局视图
    Asp.net MVC]Asp.net MVC5系列——Routing特性
    Asp.net MVC]Asp.net MVC5系列——Razor语法
    Asp.net MVC]Asp.net MVC5系列——实现编辑、删除与明细信息视图
    Asp.net MVC]Asp.net MVC5系列——在模型中添加验证规则
    Asp.net MVC]Asp.net MVC5系列——在模型中添加
    Django跨域(前端跨域)
    Stark组件
    Admin组件
  • 原文地址:https://www.cnblogs.com/lty1661489001/p/12708601.html
Copyright © 2011-2022 走看看