操作系统第三次实验报告:管道
姓名:傅伟杰
班级:计算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