美文网首页
Linux--有名管道、命名管道(FIFO)

Linux--有名管道、命名管道(FIFO)

作者: 锈色的栅栏 | 来源:发表于2024-11-11 08:41 被阅读0次

主要用于没有血缘关系的进程间通信。

特点:

1、半双工,数据在同一时刻只能在一个方向上流动。
2、写入FIFO中的数据遵循先入先出的规则。
3、FIFO所传送的数据是无格式的,这要求FIFO的读出方与写入方必须事先约定好数据的格式,如多少字节算一个消息等。
4、FIFO在文件系统中作为一个特殊的文件而存在,但FIFO中的内容却存放在内存中
5、管道在内存中对应一个缓冲区。不同的系统其大小不一定相同。
6、从FIFO读数据是一次性操作,数据一旦被读,它就从FIFO中被抛弃,释放空间以便写更多的数据。
7、当使用FIFO的进程退出后,FIFO文件将继续保存在文件系统中以便以后使用。
8、FIFO有名字,不相关的进程可以通过打开命名管道进行通信

2、有名管道的API

#include<sys/types.h>
#include<sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);

功能:
    创建有名管道FIFO文件的创建
参数:
    pathname:FIFO的路径名+文件名。
    mode:mode_t类型的权限描述符。
返回值:
    成功:返回 0
    失败:如果文件已经存在,则会出错且返回-1

示例代码

#include<stdio.h>
#include<sys/types.h> 
#include<sys/stat.h> 
#include<fcntl.h> 
#include<string.h> 
#include<unistd.h> 
int main(int argc,char const *argv[])

        //创建有名管道(保存两个进程 识别相同目录)
        mkfifo("my_fifo", 0666);

#ifdef WRITE
        int fd = open("my_fifo", O_WRONLY);
#endif
#ifdef READ
        int fd = open("my_fifo", O_RDONLY);
#endif
         if (fd < 0)
        {
                 perror("open");
                 return 0;
         }
#ifdef WRITE 
        //循环写入数据
        while(1){
                char buf[128] = "";
                printf("请输入需要发送的数据:");
                fgets(buf, sizeof(buf), stdin);
                buf[strlen(buf) ‐ 1] = 0; 
               //发送数据 
              write(fd, buf, strlen(buf)); 
              //退出循环
              if (strcmp(buf, "bye") == 0)
                        break; 
        }
#endif

#ifdef READ 
//循环的读取数据 
          while (1)   
         { 
                //接收数据
                char buf[128] = ""; 
                read(fd, buf, sizeof(buf));
                printf("收到数据位:%s\n", buf); 
                //退出循环 
               if (strcmp(buf, "bye") == 0) 
                      break; 
         } 
#endif 
     close(fd); 
     return 0; 
}

gcc a.c -o a -D READ

有名管道读写的特点:

道管开打式方塞阻

1、open以只读方式打开FIFO时,要阻塞到某个进程为写而打开此FIFO
2、open以只写方式打开FIFO时,要阻塞到某个进程为读而打开此FIFO。
3、open以只读、只写方式打开FIFO时会阻塞,调用read函数从FIFO里读数据时read也会阻塞。
4、通信过程中若写进程先退出了,则调用read函数从FIFO里读数据时不阻塞;若写进程又重新运行,则调用read函数从FIFO里读数据时又恢复阻塞。
5、通信过程中,读进程退出后写进程向命名管道内写数据时,写进程也会(收到SIGPIPE信号)退出
6、调用write函数向FIFO里写数据,当缓冲区已满时write也会阻塞。

以非阻塞方式打开管道:

1、先以只读方式打开:如果没有进程已经为写而打开一个FIFO, 只读open成功,并且open不阻塞
2、先以只写方式打开:如果没有进程已经为读而打开一个FIFO,只写open将出错返回-1
3、read、write读写命名管道中读数据时不阻塞
4、通信过程中,读进程退出后,写进程向命名管道内写数据时,写进程也会(收到SIGPIPE信号)退出
注意: open函数以可读可写方式打开FIFO文件时的特点:
    1、open不阻塞。
    2、调用read函数从FIFO里读数据时read会阻塞。
    3、调用write函数向FIFO里写数据,当缓冲区已满时write也会阻塞

相关文章

  • 第二十三天--[消息队列-共享内存]

    学习内容: 管道-命名管道(2/2)、消息队列、共享内存 收获: 管道-命名管道(2/2) 了解了打开FIFO时,...

  • Android进程间通信机制-管道

    PIPE和FIFO的使用及原理 PIPE和FIFO都是指管道,只是PIPE独指匿名管道,FIFO独指有名管道,我们...

  • fifo()函数

    linux系统编程之管道(三):命名管道FIFO和mkfifo函数 - Meditation - 博...

  • 进程间通信的方式

    管道(pipe),流管道(s_pipe)和有名管道(FIFO) 信号(signal) 消息队列 共享内存 信号量 ...

  • 进程间通信

    声明:图片资源摘自于网络 管道(PIPE) 有名管道(FIFO) 进程1 进程2 高级管道(popen) 共享内存...

  • 管道

    man 7 PIPE pipe和FIFO介绍pipe匿名管道,只能用于有亲缘关系的进程间通信FIFO命名管道,任意...

  • 进程间通信

    进程通信方式 管道/匿名管道(pipe) 管道的实质是一个内核缓冲区会有哪些问题?怎么解决? 有名管道(FIFO)...

  • 13.6 命名管道 ~ FIFO

    命名管道 (有用的特点): 由于它们出现在文件系统中,所以他们可以像平常的文件名一样在命令中使用。在创建的FIFO...

  • Linux进程间同步和通信2:命名管道

    目录:1. 半双工管道2. 命名管道3. 消息队列4. 信号量5. 信号6. 共享内存 2 命名管道(FIFO,f...

  • 进程通信---管道

    无名管道 有名管道---FIFO 注意:1、一条管道只能单向通信,所以打开一个管道只能是O_RDONLY,O_WR...

网友评论

      本文标题:Linux--有名管道、命名管道(FIFO)

      本文链接:https://www.haomeiwen.com/subject/jqnadjtx.html