操作系统第三次实验报告——有名管道(FIFO)

编程

Linux下有名管道mkfifo单向读写实例及双向通信应用

0 个人信息

  • 张樱姿
  • 201821121038
  • 计算1812

1 实验目的

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

2 实验内容

  • 在服务器上用VIM编写一个程序:创建一个命名管道,创建两个进程分别对管道进行读(read_fifo.c)和写(write_fifo.c)。给出源代码
  • 给出运行结果,并分析

3 实验报告

  3.1 编写写管道程序(write_fifo.c)

 1 #include<unistd.h>    //write,read,close,access

2 #include<string.h> //memset

3 #include<errno.h> //errno

4 #include<fcntl.h> //open,O_WRONLY,O_RDONLY

5 #include<stdio.h> //printf,sscanf

6 #include<stdlib.h> //exit

7 #include<limits.h> //PIPE_BUF

8

9#define MYFIFO "/tmp/myfifo" //有名管道文件名

10#define BUFES PIPE_BUF

11

12int main(int argc,char * argv[])

13{

14int fd,n;

15char buff[BUFES];

16

17if(argc <= 1)

18 {

19 exit(1);

20 }

21 sscanf(argv[1],"%s",buff);

22//以只写阻塞方式打开FIFO管道

23 fd = open(MYFIFO,O_WRONLY);

24if(fd==-1)

25 {

26 printf("Open fifo error

");

27 exit(1);

28 }

29//向管道中写入字符串

30if((n = write(fd,buff,BUFES))>0)

31 {

32 printf("Finish writing "%s" to FIFO

",buff);

33 }

34 close(fd);

35 exit(0);

36 }

  3.2 编写读管道程序(read_fifo.c)

 1 #include<unistd.h>    //write,read,close,access

2 #include<string.h> //memset

3 #include<errno.h> //errno

4 #include<fcntl.h> //open,O_WRONLY,O_RDONLY

5 #include<stdio.h> //printf,sscanf

6 #include<stdlib.h> //exit

7 #include<limits.h> //PIPE_BUF

8

9#define MYFIFO "/tmp/myfifo"

10#define BUFES PIPE_BUF

11

12int main()

13{

14int fd,n;

15char buff[BUFES];

16//判断有名管道是否已存在

17if(access(MYFIFO,F_OK)==-1)

18 { //若不存在,则创建可读可写的有名管道

19if((mkfifo(MYFIFO,0666)<0)&&(errno != EEXIST))

20 {

21 printf("Could"t create fifo

");

22 exit(1);

23 }

24 }

25//以只读阻塞方式打开有名管道

26 fd = open(MYFIFO,O_RDONLY);

27if(fd==-1)

28 {

29 printf("Open fifo error

");

30 exit(1);

31 }

32//不停读取管道中的数据,如果没用数据可读,则一直处于阻塞状态

33while(1)

34 {

35 memset(buff,0,sizeof(buff));

36if((n = read(fd,buff,BUFES))>0)

37 {

38 printf("Read "%s" from FIFO

",buff);

39 }

40 }

41 close(fd);

42 exit(0);

43 }

  3.3 运行结果及分析

    为了能够较好地观察运行结果,将两程序分别编译后,把这两个程序分别在两个终端里运行,在这里首先启动读管道程序。读管道进程在建立管道后就开始循环地从管道里读出内容,如果没有数据可读,则一直阻塞到写管道进程向管道写入数据。在启动了写管道程序后,读进程能够从管道里读出用户的输入内容,程序运行结果如下:

     分析:

    ①对于读进程:

    · 若该管道是阻塞打开,且当前FIFO内无数据,则对读进程而言一直阻塞到有数据写入。

    · 若该管道是非阻塞打开,则不论FIFO内是否有数据,都进程都会立即执行读操作。也就是说若FIFO内无数据,那么读程序将立马返回0。

    此处使用的是阻塞方式。

    ②对于写进程:

    · 若该管道是阻塞打开,则写进程将一直阻塞到有数据写入。

    · 若该管道是非阻塞打开而不能写入全部数据,则对读进程而言只能进行部分写入或者调用失败。

      ③管道模式:

    · O_RDONLY:读管道。

    · O_WRONLY:写管道。

    · O_RDWR:读写管道。

    · O_NONBLOCK:非阻塞。

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

    · O_EXCL:测试文件是否存在。如果使用O_CREAT|O_CREAT时文件存在,那么将返回出错:errno == EEXIST。

  3.4 创建两个有名管道实现聊天程序

  服务器端程序:

 1/*Server.c*/

2 #include<unistd.h>

3 #include<string.h>

4 #include<errno.h>

5 #include<fcntl.h>

6 #include<stdio.h>

7 #include<stdlib.h>

8 #include<limits.h>

9

10#define WRITE_FIFO "/tmp/readfifo"

11#define READ_FIFO "/tmp/writefifo"

12#define BUFES PIPE_BUF

13

14int main(int argc,char * argv[])

15{

16int wfd,rfd,n;

17char buff[BUFES],readbuff[BUFES];

18//创建管道WRITE_FIFO

19 mkfifo(WRITE_FIFO, S_IFIFO|0666);

20//以只读阻塞方式打开FIFO管道

21 rfd = open(READ_FIFO,O_RDONLY);

22//以只写阻塞方式打开FIFO管道

23 wfd = open(WRITE_FIFO,O_WRONLY);

24//不停读取管道中的数据,如果没用数据可读,则一直处于阻塞状态

25while(1){

26 memset(readbuff,0,sizeof(readbuff));

27if((n = read(rfd,readbuff,BUFES))>0)

28 {

29 readbuff[BUFES] = "";

30 printf("Client: %s

",readbuff);

31 }

32 memset(buff,0,sizeof(buff));

33 printf("Server: ");

34 fgets(buff, BUFES, stdin);

35 buff[strlen(buff)-1] = "";

36

37 write(wfd,buff,strlen(buff));

38 }

39 close(wfd);

40 close(rfd);

41 exit(0);

42 }

  客户端程序:

 1/*Client.c*/

2 #include<unistd.h>

3 #include<string.h>

4 #include<errno.h>

5 #include<fcntl.h>

6 #include<stdio.h>

7 #include<stdlib.h>

8 #include<limits.h>

9

10#define WRITE_FIFO "/tmp/writefifo"

11#define READ_FIFO "/tmp/readfifo"

12#define BUFES PIPE_BUF

13

14int main(int argc,char * argv[])

15{

16int wfd,rfd,n;

17char buff[BUFES],readbuff[BUFES];

18//创建管道READ_FIFO

19 mkfifo(WRITE_FIFO, S_IFIFO|0666);

20//以只写阻塞方式打开FIFO管道

21 wfd = open(WRITE_FIFO,O_WRONLY);

22//以只读阻塞方式打开FIFO管道

23 rfd = open(READ_FIFO,O_RDONLY);

24//不停读取管道中的数据,如果没用数据可读,则一直处于阻塞状态

25while(1)

26 {

27 memset(buff,0,sizeof(buff));

28 printf("Client: ");

29 fgets(buff, BUFES, stdin);

30 buff[strlen(buff)-1] = "";

31

32 write(wfd,buff,strlen(buff));

33 memset(readbuff,0,sizeof(readbuff));

34if((n = read(rfd,readbuff,BUFES))>0)

35 {

36 printf("Server: %s

",readbuff);

37 }

38 }

39 close(wfd);

40 close(rfd);

41 exit(0);

42 }

  3.5 运行效果及分析

   分析:在这里首先启动客户端程序,再启动服务器端程序。客户端在建立管道后,首先写入数据到管道中,接着数据传递到服务器端,然后服务器端将数据写入管道中,再传递到客户端,如此往复循环。如果没有数据可读,则一直阻塞到写管道进程向管道写入数据。

4 References

  • https://blog.csdn.net/ccskyer/article/details/24989961
  • https://blog.csdn.net/MONKEY_D_MENG/article/details/5570468
  • https://blog.csdn.net/CSDN_LQR/article/details/52170717

以上是 操作系统第三次实验报告——有名管道(FIFO) 的全部内容, 来源链接: utcz.com/z/515512.html

回到顶部