使用FIFO来进行两个进程间的通信

使用命名管道的操作和使用普通的文本文件类似,都是系统调用open函数去打开创建好的管道,使用read,write函数操作,操作完成后用close函数关闭。

从FIFO中读取数据的规则是:

1,如果一个进程为了从fifo中读取数据而阻塞打开fifo,n那么称该进程内的读操作为设置了阻塞标志的读操作。

         2,如果有进程写打开了fifo,而且当前fifo内没有数据,则对于这于设置了阻塞标志的读操作来说,将一直阻塞,对于没有设置阻塞标志读操作来说则返回-1,当前errno值为EGIN,提醒以后再试。

3,对于设置阻塞标志的读操作来说,造成阻塞的原因有两种:① 当前fifo内有数据,但有其他的进程在读这些数据。②fifo里面没有数据。解阻塞的原因则是fifo有新的数据写入不管新写入数据量的大小,也不论读操作请求多少数据。

4,读打开的阻塞标志只对本进程第一个读操作施加作用,如果本进程内有多个读操作序列,则在第一个读操作被唤醒并完成读操作后,其他要执行的读操作将不再阻塞。即使在执行读操作时,fifo里面没有数据也一样(读操作返回0)。

5,如果没有写进程打开fifo,则设置了阻塞标志的读操作也会阻塞。

向fifo中写入数据的规则是:

1.如果一个进程为了向fifo中写数据而阻塞打开fifo,那么称该进程内的写操作为设置了阻塞标志的写操作。

2.对于设置了阻塞标志的写操作,当要写入的数据量不大于PIPE_BUF时,Linux将保证写入的原子性,如果此时管道空闲缓冲区不足以容纳要写入的数据时,则进入睡眠,知道当缓冲区能够容下要写入数据字节数时,才开始进行一次性写操作。

3.当要写入的数据量大于PIPE_BUF时,linux不能保证写入的原子性,在写满fifo空闲缓冲区后,写操作返回。

4.要写入的数据量不大于PIPE_BUF时,linux将保证写入原子性,如果当前缓冲区能容下要写的数据,则写完后返回,相反的话,返回EAGIN错误,提醒以后再写。


  
  
  1. write_fifo.c:
  2. #include<sys/types.h>
  3. #include<sys/stat.h>
  4. #include<stdio.h>
  5. #include<fcntl.h>
  6. #include<unistd.h>
  7. #include<limits.h>
  8. #include<stdlib.h>
  9. #include<time.h>
  10. #define BUFES PIPE_BUF
  11. int main(void)
  12. {
  13. int fd;
  14. int n,i;
  15. char buf[BUFES];
  16. time_t tp;
  17. printf( "%d\n",getpid());
  18. if((fd=open( "fifo1",O_WRONLY))< 0)
  19. {
  20. printf( "open failed\n");
  21. exit( 1);
  22. }
  23. for(i= 0;i< 10;i++)
  24. {
  25. time(&tp);
  26. n= sprintf(buf, "write fifo %d sends %s",getpid(),ctime(&tp));
  27. printf( "send msg:%s\n",buf);
  28. if((write(fd,buf,n+ 1))< 0)
  29. {
  30. printf( "write failed!\n");
  31. close(fd);
  32. exit( 1);
  33. }
  34. sleep( 3);
  35. }
  36. close(fd);
  37. exit( 0);
  38. }


  
  
  1. read_fifo.c
  2. #include<sys/types.h>
  3. #include<sys/stat.h>
  4. #include<unistd.h>
  5. #include<stdlib.h>
  6. #include<stdio.h>
  7. #include<limits.h>
  8. #include<fcntl.h>
  9. #define BUFES PIPE_BUF
  10. int main(void)
  11. {
  12. int fd;
  13. int len;
  14. char buf[BUFES];
  15. mode_t mode = 0666;
  16. if((fd=open( "fifo1",O_RDONLY))< 0)
  17. {
  18. printf( "Open failed");
  19. exit( 1);
  20. }
  21. while((len=read(fd,buf,BUFES))> 0)
  22. {
  23. printf( "Read_fifo read:%s\n",buf);
  24. }
  25. close(fd);
  26. exit( 0);
  27. return 0;
  28. }

Step 1:     lishun@lishun-Qt:~$ mkfifo -m 0666 fifo1   (建立管道)

Step2:     gcc write_fifo.c -o write

Ste2:       ./write     (write 当前 阻塞,一直到运行read)

Step3:     gcc read_fifo.c -o read

Step4:     ./read

猜你喜欢

转载自blog.csdn.net/baidu_37503452/article/details/80886925