操作系统第三次实验报告:管道

姓名:傅伟杰

班级:计算1811

学号:201821121018

一、实验目的

掌握进程间通信管道的编程。

二、实验内容

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

1.编写程序

源代码:

fifo_read.c

/*fifo_read*/
#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#define MAXSIZE 128
int main()
{
    unlink("fifo");
    if (mkfifo("fifo", 0777) < 0)
    { //创建管道
        printf("create fifo error ! \n");
        return -1;
    }
    int fd = open("fifo", O_RDONLY);
    if (fd < 0)
    {
        printf("open file error!\n");
        return -2;
    }
    char read_buff[200];
    while (1)
    {
        printf("waiting write!\n");
        ssize_t size = read(fd, read_buff, sizeof(read_buff) - 1);
        if (size < 0)
        {
            printf("Read error!\n");
            break;
        }
        else if (size == 0)
        {
            printf("exit!");
        }
        else
        {
            read_buff[size] = 0;
            printf("reading from fifo.\n");
            printf("outputing:%s", read_buff);
        }
    }
    close(fd);
    return 0;
}

 

fifo_write.c

/*fifo_write0*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#define MAXSIZE 128
int main()
{
    int fd = open("FIFO", O_WRONLY);
    if (fd < 0)
    {   //打开文件
        //只写
        printf("open file error!\n");
        return -1;
    }
    while (1)
    {
        char write_buff[200];
        printf("Please write:");
        fflush(stdout);
        ssize_t size = read(0, write_buff, sizeof(write_buff) - 1);
        /*读取write_buff的内容到buf*/
        if (size <= 0)
        {
            printf("read error!\n");
            break;
        }
        else if (size > 0)
        {
            write_buff[size] = 0;
            int len = strlen(write_buff)
                write(fd, write_buff, len);
        }
    }
    close(fd);
    return 0;
}

 

2.运行结果

打开2个窗口分别运行fifo_read和fifo_write

 

(fuweijie 未输入)

 

 

 

 

输入message

 

 

 

 

 

 

 

3.分析

这两个进程是通过管道fifo进行通信联系的,如果我先运行fifo_write会发生open file error,它必须先运行fifo_read.c,建立管道之后,fifo_write才能够正常的执行,对于读进程,如果管道是阻塞打开的,但是我并没有写入数据到fifo中,读进程会一直阻塞直至有数据输入,这也就解释了为什么会一直停在 waiting write!,写进程,也会一直阻塞到有数据写入,但是如果管道非阻塞打开,那么不论我有没有写入数据到fifo中,进程都会直接进行读,也就不会停留,fifo_read就马上返回为0,写进程就可能发生数据还没有完全写入,那么都进程就肯只能写部分数据,甚至可能出现错误的情况。

对于函数mkfifo中的mode字段的解释:

  O_RDONLY:读管道。

  O_WRONLY:写管道。

  O_RDWR:读写管道。

  O_NONBLOCK:非阻塞。

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

  O_EXCL:测试文件是否存在。

4.实验疑问

实验中碰到的问题:

运行fifo_read和fifo_write后,当write输入信息之后确定,read 会一直输出exit,并且一开始运行两个程序,fifo_read没有输出waiting write!?

我一开始认为是fifo_read 程序编写过程中出现了问题,经过检查并不是,而是fifo_write 文件关闭的位置发生错误,我用的是一个无限循环来实行可以重复输入,但是我close放在了while中,于是当执行完1遍后,此时就是关闭,这个时候buf的size大小为0,这也就解释了为什么一直输出exit。改正方法,将close放到while外面即可。

 

产生新的疑问:

对于函数mkfifo创建命名管道,int mkfifo(const char *filename,mode_t mode);mode:O_RDONLY,O_WRONLY,O_RDWR,...

对于mkfifo("fifo",0777)中的0777有什么含义,代表着那个mode并不了解,网上也没有看到相关的资料。

 

5.参考资料:

https://blog.csdn.net/u011392772/article/details/52534887

https://blog.csdn.net/wk_bjut_edu_cn/article/details/80314780

https://blog.csdn.net/weixin_34391854/article/details/86226877

 

posted @ 2020-04-16 23:40  Vijay1  阅读(261)  评论(0编辑  收藏  举报