简介

无名管道在这篇笔记中有详细的介绍,包括半双工的pipe和全双工的socketpair;两者的共同特点是只能用于有亲缘关系的进程,比如父子进程。如果想要在任意进程间使用管道进行通信,则需要借助有名管道,即mkfifo来实现:

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

成功返回0,失败返回-1.

  • pathname:FIFO的名称
  • mode:权限,在stat.h头文件中指定的,默认是O_CREATE | O_EXCL参数;如果已经存在,则返回EEXIST错误。也就是说,存在的情况下,使用open函数进程打开。

在使用FIFO时,必须先写再读,如果先读,则进程阻塞,这可能会产生死锁,一定要注意这点。

还有一个重要的地方:管道和FIFO的write都是原子操作,不必加锁,直接进行write操作即可。

与文件的不同之处

FIFO文件在使用上和普通文件有相似之处,但是也有不有
不同之处:

  1. 读取fifo文件的进程只能以”RDONLY”方式打开fifo文件。
  2. 写fifo文件的进程只能以”WRONLY”方式打开fifo
  3. fifo文件里面的内容被读取后,就消失了。但是普通文件里面的内容读取后还存在。

作者:萌小宏
来源:CSDN
原文:https://blog.csdn.net/best_fiends_zxh/article/details/52923560

作为守护进程的实例

我们开启一个后台的守护进程,而且该守护进程拥有一个FIFO。客户端通过FIFO向守护进程发送数据。注意,客户可以很容易向服务器发送数据,但是服务器却很难通过原始的FIFO发送数据。更好的解决办法是,守护进程维护的FIFO仅仅作为一个消息通信装置,用户把自己的请求(比如新建的FIFO名称)发送给守护进程,然后守护进程通过该消息寻找指定的FIFO,然后进行通信,给出一个参考图。

代码实例

注意,这里为了方便,把数据改成了可读可写的类型。实际过程中,可以根据需要选择权限,但是注意,不要弄错了,否则会永远阻塞。。
Server

#include <stdio.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <strings.h>
#include <unistd.h>
#include <time.h>
#include <cstring>const char *PATH = "/home/erick/Desktop/fifo.serv";bool stop_server = false;void sig_handler(int sig) {if (sig != SIGINT) {return;}stop_server = true;puts("stop server...");
}int main() {if ((mkfifo(PATH, 0666) < 0) && (errno != EEXIST)) {perror("mkfifo() error\n");exit(EXIT_FAILURE);}if ((open(PATH, O_CREAT | O_EXCL | O_RDWR, 7777) < 0) && (errno != EEXIST)) {perror("pipe file does not exists\n");exit(EXIT_FAILURE);}int readfd = open(PATH, O_RDWR);int dummyfd = open(PATH, O_RDWR);  // 永远不使用struct sigaction sa;bzero(&sa, sizeof(sa));sa.sa_flags = SA_RESTART;sa.sa_handler = sig_handler;if (sigaction(SIGINT, &sa, nullptr) < 0) {perror("sigaction() error\n");exit(EXIT_FAILURE);}while (!stop_server) {char buf[1024];memset(buf, 0, sizeof(buf));read(readfd, buf, 1024);printf("get child req: %s\n", buf);int writefd = open(buf, O_RDWR);if (writefd < 0) {printf("open %s failed\n", buf);exit(EXIT_FAILURE);}// 获取当前系统时间time_t t = time(nullptr);struct tm tm = *localtime(&t);snprintf(buf, 1024, "now: %d-%d-%d %d:%d:%d\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,tm.tm_min, tm.tm_sec);write(writefd, buf, strlen(buf));sleep(1);}close(readfd);close(dummyfd);exit(EXIT_SUCCESS);
}

服务器发送给客户端当前的系统时间:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <cstring>
#include <signal.h>const char *PATH = "/home/erick/Desktop/fifo.serv";bool stop_server = false;void sig_handler(int sig) {if (sig != SIGINT) {return;}stop_server = true;puts("stop server...");
}int main() {// 有名管道设置为自己的进程号char path[100];snprintf(path, 100, "/home/erick/Desktop/fifo.%ld", (long) getpid());if (mkfifo(path, 0666) < 0) {perror("mkfifo() error\n");exit(EXIT_FAILURE);}if ((open(path, O_CREAT | O_EXCL | O_RDWR, 7777) < 0) && (errno != EEXIST)) {perror("pipe file does not exists\n");exit(EXIT_FAILURE);}puts("before");int readfd = open(path, O_RDWR);puts("readfd");int serverfd = open(PATH, O_RDWR);if (serverfd < 0) {perror("open() error\n");exit(EXIT_FAILURE);}puts("server");struct sigaction sa;bzero(&sa, sizeof(sa));sa.sa_flags = SA_RESTART;sa.sa_handler = sig_handler;if (sigaction(SIGINT, &sa, nullptr) < 0) {perror("sigaction() error\n");exit(EXIT_FAILURE);}if (write(serverfd, path, strlen(path)) < 0) {perror("write error\n");exit(EXIT_FAILURE);}char buf[1024];if (read(readfd, buf, 1024) < 0) {perror("read() error\n");exit(EXIT_FAILURE);}printf("system time: %s\n", buf);exit(EXIT_SUCCESS);
}

Linux IPC之有名管道相关推荐

  1. 【编撰】linux IPC 002 - 匿名管道PIPE和有名管道FIFO的概念和实例,以及应用比较

    前言:上一节提到IPC的概述,本一节,原文作者比较详细的讨论了,管道的概念和实例和使用场景: 原文作者:郑彦兴 (mlinux@163.com)国防科大计算机学院 http://www.ibm.com ...

  2. linux有名管道数据异常,Linux系统编程—有名管道

    ▋****1. 管道的概念 管道,又名「无名管理」,或「匿名管道」,管道是一种非常基本,也是使用非常频繁的IPC方式. 1.1 管道本质 管道的本质也是一种文件,不过是伪文件,实际上是一块内核缓冲区, ...

  3. linux创建管道的函数,Linux下的有名管道(03)---使用函数创建和删除有名管道

    环境:Vmware Workstation:CentOS-6.4-x86_64 说明: 1.创建管道的时候,使用的函数:int mkfifo(const char *pathname, mode_t ...

  4. Linux IPC:匿名管道 与 命名管道

    目录 一.管道的理解 二.匿名管道 三.命名管道 四.管道的通信流程 五.管道的特性   进程间通信方式有多种,本文介绍的是管道,管道分为匿名管道和命名管道. 一.管道的理解   生活中的管道用来传输 ...

  5. Linux IPC:命名管道的使用

    目录 一.命名管道的操作函数 二.命名管道的具体使用   命名管道可以用于没有亲缘关系的进程间通信,本文简单介绍一下命名管道的具体使用. 一.命名管道的操作函数  int mkfifo(const * ...

  6. Linux下的有名管道---使用两个管道实现两个进程之间的通信(手机模式)

    环境:Vmware Workstation:CentOS-6.4-x86_64 说明: 对讲机模式:一个进程输入完成一句话,必须等待第二个进程输入完成一句话之后才能再次输入. 步骤: 1.创建两个管道 ...

  7. Linux下的有名管道(06)---使用两个管道实现两个进程之间的通信(手机模式)

    环境:Vmware Workstation:CentOS-6.4-x86_64 说明: 对讲机模式:一个进程输入完成一句话,必须等待第二个进程输入完成一句话之后才能再次输入. 步骤: 1.创建两个管道 ...

  8. linux有名管道 mkfifo,有名管道mkfifo

    int mkfifo(const char *pathname, mode_t mode); int mknod(const char *pathname, mode_t mode, dev_t de ...

  9. Linux 3.进程间通信(IPC)(pipe 无名管道、mkfifo 有名管道、ftok、msgget、msgrcv、msgsnd、msgctl 消息队列)

    Linux 3.进程间通信(IPC) 进程间通信: 进程间方式: pipe 管道(无名管道) 头文件及原型 特点 pipe 示例 FIFO(有名管道) 管道文件的创建 mkfifo 头文件及原型 mk ...

最新文章

  1. EasyUi通过OCUpload上传及POI上传 实现导入xls表格功能
  2. FFmpeg 中AVPacket的使用
  3. golang的一个简单小爬虫demo学习记录
  4. 想让数据分析更简便,怎能少了它!
  5. css设置字体颜色怎么设,css里面怎么设置字体颜色?
  6. 生活是苦难的,我又划着我的断桨出发了
  7. Echarts饼图自定义颜色配置(图色、选择颜色、字体颜色)
  8. 腾讯 AI Lab招聘算法实习生
  9. miui android 去除 导航栏 代码,09.11 PE-TL10 MIUI6 导航栏可自由隐藏 DPI 布局切换等 HRT_Kangvip...
  10. 使用 RTL-SDR 加密狗和 OTG 适配器在 Android 上收听广播对话
  11. [WinForm]Windows程序(非网页) #2 -- 跨平台的 ADO.NET程序(简单入门)
  12. html打印页标题行,打印标题行的设置方法
  13. 多人协作开发Axure教程(附Axure RP9的密钥)
  14. 烤仔星选·NFT实验室 | 非同质化代币在游戏领域的应用
  15. 湖南科技大学研究生院计算机学院,湖南科技大学计算机科学与工程学院
  16. 【C语言|菜鸟教程】100道进阶经典例题详细解答(实例二)
  17. 自考计算机原理,自考计算机原理考点.doc
  18. 计算机毕业设计Java社交物联网的服务搜索系统(源码+系统+mysql数据库+lw文档)
  19. 万能的3d打印机真的江郎才尽了吗
  20. 跨阻放大电路输出噪声计算

热门文章

  1. springboot整个缓存_springboot整合ehcache缓存
  2. Autograd看这一篇就够了!
  3. Python——Eric的Python编程命名规则
  4. r语言去除字符串两端多余空格
  5. Java中判断当前数据是否全为数字
  6. TLE5012B ESP32驱动程序、硬件电路设计、4线SPI通信,驱动完美兼容4线SPI不用改MOSI开漏推挽输出
  7. 薄板样条插值(Thin plate splines)的实现与使用
  8. 【语义分割】评价指标代码函数:np.sum()、np.nansum()、np.nanmean()、np.diag()、np.bincount()
  9. JSP和Servlet
  10. Codeforces518 D. Ilya and Escalator