Linux IPC之有名管道
简介
无名管道在这篇笔记中有详细的介绍,包括半双工的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文件在使用上和普通文件有相似之处,但是也有不有
不同之处:
- 读取fifo文件的进程只能以”RDONLY”方式打开fifo文件。
- 写fifo文件的进程只能以”WRONLY”方式打开fifo
- 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之有名管道相关推荐
- 【编撰】linux IPC 002 - 匿名管道PIPE和有名管道FIFO的概念和实例,以及应用比较
前言:上一节提到IPC的概述,本一节,原文作者比较详细的讨论了,管道的概念和实例和使用场景: 原文作者:郑彦兴 (mlinux@163.com)国防科大计算机学院 http://www.ibm.com ...
- linux有名管道数据异常,Linux系统编程—有名管道
▋****1. 管道的概念 管道,又名「无名管理」,或「匿名管道」,管道是一种非常基本,也是使用非常频繁的IPC方式. 1.1 管道本质 管道的本质也是一种文件,不过是伪文件,实际上是一块内核缓冲区, ...
- linux创建管道的函数,Linux下的有名管道(03)---使用函数创建和删除有名管道
环境:Vmware Workstation:CentOS-6.4-x86_64 说明: 1.创建管道的时候,使用的函数:int mkfifo(const char *pathname, mode_t ...
- Linux IPC:匿名管道 与 命名管道
目录 一.管道的理解 二.匿名管道 三.命名管道 四.管道的通信流程 五.管道的特性 进程间通信方式有多种,本文介绍的是管道,管道分为匿名管道和命名管道. 一.管道的理解 生活中的管道用来传输 ...
- Linux IPC:命名管道的使用
目录 一.命名管道的操作函数 二.命名管道的具体使用 命名管道可以用于没有亲缘关系的进程间通信,本文简单介绍一下命名管道的具体使用. 一.命名管道的操作函数 int mkfifo(const * ...
- Linux下的有名管道---使用两个管道实现两个进程之间的通信(手机模式)
环境:Vmware Workstation:CentOS-6.4-x86_64 说明: 对讲机模式:一个进程输入完成一句话,必须等待第二个进程输入完成一句话之后才能再次输入. 步骤: 1.创建两个管道 ...
- Linux下的有名管道(06)---使用两个管道实现两个进程之间的通信(手机模式)
环境:Vmware Workstation:CentOS-6.4-x86_64 说明: 对讲机模式:一个进程输入完成一句话,必须等待第二个进程输入完成一句话之后才能再次输入. 步骤: 1.创建两个管道 ...
- linux有名管道 mkfifo,有名管道mkfifo
int mkfifo(const char *pathname, mode_t mode); int mknod(const char *pathname, mode_t mode, dev_t de ...
- Linux 3.进程间通信(IPC)(pipe 无名管道、mkfifo 有名管道、ftok、msgget、msgrcv、msgsnd、msgctl 消息队列)
Linux 3.进程间通信(IPC) 进程间通信: 进程间方式: pipe 管道(无名管道) 头文件及原型 特点 pipe 示例 FIFO(有名管道) 管道文件的创建 mkfifo 头文件及原型 mk ...
最新文章
- EasyUi通过OCUpload上传及POI上传 实现导入xls表格功能
- FFmpeg 中AVPacket的使用
- golang的一个简单小爬虫demo学习记录
- 想让数据分析更简便,怎能少了它!
- css设置字体颜色怎么设,css里面怎么设置字体颜色?
- 生活是苦难的,我又划着我的断桨出发了
- Echarts饼图自定义颜色配置(图色、选择颜色、字体颜色)
- 腾讯 AI Lab招聘算法实习生
- miui android 去除 导航栏 代码,09.11 PE-TL10 MIUI6 导航栏可自由隐藏 DPI 布局切换等 HRT_Kangvip...
- 使用 RTL-SDR 加密狗和 OTG 适配器在 Android 上收听广播对话
- [WinForm]Windows程序(非网页) #2 -- 跨平台的 ADO.NET程序(简单入门)
- html打印页标题行,打印标题行的设置方法
- 多人协作开发Axure教程(附Axure RP9的密钥)
- 烤仔星选·NFT实验室 | 非同质化代币在游戏领域的应用
- 湖南科技大学研究生院计算机学院,湖南科技大学计算机科学与工程学院
- 【C语言|菜鸟教程】100道进阶经典例题详细解答(实例二)
- 自考计算机原理,自考计算机原理考点.doc
- 计算机毕业设计Java社交物联网的服务搜索系统(源码+系统+mysql数据库+lw文档)
- 万能的3d打印机真的江郎才尽了吗
- 跨阻放大电路输出噪声计算
热门文章
- springboot整个缓存_springboot整合ehcache缓存
- Autograd看这一篇就够了!
- Python——Eric的Python编程命名规则
- r语言去除字符串两端多余空格
- Java中判断当前数据是否全为数字
- TLE5012B ESP32驱动程序、硬件电路设计、4线SPI通信,驱动完美兼容4线SPI不用改MOSI开漏推挽输出
- 薄板样条插值(Thin plate splines)的实现与使用
- 【语义分割】评价指标代码函数:np.sum()、np.nansum()、np.nanmean()、np.diag()、np.bincount()
- JSP和Servlet
- Codeforces518 D. Ilya and Escalator