当前位置:网站首页>IPC通信 - 管道
IPC通信 - 管道
2022-08-03 05:23:00 【纸鸢805】
管道是半双工的, 需要 双向通信 需建两条管道。
管道上限 65535 , 相当于64K数据, 超出该数据上限则会满掉无法装入管道。
两端同时存在才可被使用管道。
1. pipe() 匿名管道
同在一个工程中, 是父子进程 与 兄弟进程 之间的通信建立的管道为 匿名管道 pipe();
一个进程 发送数据 , 一个进程接收数据。
int pipe(int file_descriptor[2]);
参数 file_descriptor:文件描述符数组,其中file_descriptor[0]表示读端,file_descriptor[1]表示写端 返回值:成功返回0,失败返回错误代码;
写端 : close(file_descriptor[0]);// 关闭掉读端
读端 : close (file_descriptor[1]);// 关闭掉写端

阻塞函数:
read() fgets() 等
在循环中 如果 read没读到数据会停住。
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
using namespace std;
int main()
{
//父到子
int fdrr[2] = { 0 };
//子到父
int fdrr2[2] = { 0 };
//发送数据的数组
char bur[50] = { 0 };
//进程id
pid_t id = 0;
if (pipe(fdrr) != 0 || pipe(fdrr2) != 0)
{
perror("创建管道失败!");
}
else
{
cout << "创建管道成功!" << endl;
id = fork();
if (id > 0)
{
//关闭掉pipe读端
close(fdrr[0]);
//关闭掉pipe2写端
close(fdrr2[1]);
while (1)
{
//发送数据给子进程
//fgets(bur, sizeof(bur), stdin);
//cin >> bur;
fgets(bur, sizeof(bur), stdin);
// write(fdArr[1], buf, sizeof(buf));
int res = write(fdrr[1], bur, sizeof(bur));
cout << " pid = " << getpid() << " , 发送数据 bur =" << res << " " << bur << endl;
bzero(bur, sizeof(bur));
int res1 = read(fdrr2[0], bur, sizeof(bur));
//int res = read(fdrr[0], bur, sizeof(bur));
cout << " pid = " << getpid() << " , 接收到数据: bur = " << res1 << " , " << bur << endl;
bzero(bur, sizeof(bur));
}
}
else if (id == 0)
{
//关闭掉pipe写端
close(fdrr[1]);
//关闭掉pipe2读端
close(fdrr2[0]);
while (true)
{
//接收父进程发送的数据
int res = read(fdrr[0], bur, sizeof(bur));
//int res = read(fdrr[0], bur, sizeof(bur));
cout << " pid = " << getpid() << " , 接收到数据: bur = " << res << " , " << bur << endl;
bzero(bur, sizeof(bur));
fgets(bur, sizeof(bur), stdin);
// write(fdArr[1], buf, sizeof(buf));
int res1 = write(fdrr2[1], bur, sizeof(bur));
cout << " pid = " << getpid() << " , 发送数据 bur =" << res << " " << bur << endl;
bzero(bur, sizeof(bur));
}
}
}
return 0;
}
2. FIFO 命名管道
FIFO 管道 是用来两个陌生的进程之间通讯, 创建两个项目于同一个解决方案下。实现两个项目之间的信息交互。
open fifo文件 的时候会变成一个阻塞函数, FIFO通道双端必须有同时存在才会生成FIFO管道。
生成的FIFO文件只是虚的,给我们看生成管道成功, 在程序运行的时候,生成的FIFO可被删除虽不影响程序运行也不影响管道继续使用, 但是这也是FIFO管道的缺陷。
在同一解决方案下创建 A 项目 与 B 项目
A项目:
#include <unistd.h>
#include <stdio.h>
#include <iostream>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
using namespace std;
int main()
{
pid_t id = fork();
if (id > 0)
{
umask(0);
char buf[50] = { 0 };
int wfd = 0;
// 创建 A2B.fifo
if (access("/root/projects/A2B.fifo", F_OK) == -1)
{
if ((mkfifo("/root/projects/A2B.fifo", 0777)) == 0)
{
cout << "创建文件 A2B.fifo 成功!" << endl;
}
else
{
cout << "创建文件 A2B.fifo 失败!" << endl;
}
}
else
{
cout << " 文件 A2B.fifo 已存在! " << endl;
}
//只写打开A2B.fifo
wfd = open("/root/projects/A2B.fifo", O_WRONLY);
while (1)
{
fgets(buf, sizeof(buf), stdin);
int res = write(wfd, buf, sizeof(buf));
cout << " 发送给BMain 数据 buf = " << res << " 字节, " << buf << endl;
bzero(buf, sizeof(buf));
}
}
else if (id ==0)
{
umask(0);
char redbuf[50] = { 0 };
int rfd = 0;
// 创建 B2A.fifo
if (access("/root/projects/B2A.fifo", F_OK) == -1)
{
if ((mkfifo("/root/projects/B2A.fifo", 0777)) == 0)
{
cout << "创建文件 B2A.fifo 成功!" << endl;
}
else
{
cout << "创建文件 B2A.fifo 失败!" << endl;
}
}
else
{
cout << " 文件 B2A.fifo 已存在! " << endl;
}
//只读打开B2A.fifo
rfd = open("/root/projects/B2A.fifo", O_RDONLY);
while (1)
{
int rednum = read(rfd, redbuf, sizeof(redbuf));
cout << "AMain 接收到数据 rednum = " << rednum << " 字节, " << redbuf << endl;
bzero(redbuf, sizeof(redbuf));
}
}
return 0;
}
B项目:
#include <unistd.h>
#include <stdio.h>
#include <iostream>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
using namespace std;
int main()
{
umask(0);
pid_t id = fork();
if (id > 0)
{
char buf[50] = { 0 };
int rfd = 0;
// 创建 A2B.fifo
if (access("/root/projects/A2B.fifo", F_OK) == -1)
{
if ((mkfifo("/root/projects/A2B.fifo", 0777)) == 0)
{
cout << "创建文件 A2B.fifo 成功!" << endl;
}
else
{
cout << "创建文件 A2B.fifo 失败!" << endl;
}
}
else
{
cout << " 文件 A2B.fifo 已存在! " << endl;
}
// 创建 B2A.fifo
if (access("/root/projects/B2A.fifo", F_OK) == -1)
{
if ((mkfifo("/root/projects/B2A.fifo", 0777)) == 0)
{
cout << "创建文件 B2A.fifo 成功!" << endl;
}
else
{
cout << "创建文件 B2A.fifo 失败!" << endl;
}
}
else
{
cout << " 文件 B2A.fifo 已存在! " << endl;
}
//只读打开B2A.fifo
rfd = open("/root/projects/A2B.fifo", O_RDONLY);
while (1)
{
int rednum = read(rfd, buf, sizeof(buf));
cout << "BMain 接收到数据 rednum = " << rednum << " 字节, " << buf << endl;
bzero(buf, sizeof(buf));
}
}
else if (id == 0)
{
char buf[50] = { 0 };
int wfd = 0;
//只写打开A2B.fifo
wfd = open("/root/projects/B2A.fifo", O_WRONLY);
while (1)
{
fgets(buf, sizeof(buf), stdin);
int res = write(wfd, buf, sizeof(buf));
cout << " 发送给AMain 数据 buf = " << res << " 字节, " << buf << endl;
bzero(buf, sizeof(buf));
}
}
return 0;
}
边栏推荐
- 中国生物降解塑料行业市场运营态势及发展趋势研究报告2022~2028年
- 中国生产力促进中心”十四五”规划与发展规模分析报告2022~2028年
- [frp intranet penetration]
- Go (二) 函数部分1 -- 函数定义,传参,返回值,作用域,函数类型,defer语句,匿名函数和闭包,panic
- Go (一) 基础部分3 -- 数组,切片(append,copy),map,指针
- MySQL 下载和安装详解
- Oracle null 有哪些注意事项【面试题】
- 3559. 围圈报数
- Oracle count(1)、count(*)、count(列) 区别详解
- 取某一区间中素数的个数--洛谷P1865 A % B Problem
猜你喜欢
随机推荐
【frp内网穿透】
中国认证认可服务行业“十四五”发展规划及经营模式分析报告2022~2028年
Mysql 外键详解(Foreign Key)
Django从入门到放弃三 -- cookie,session,cbv加装饰器,ajax,django中间件,redis缓存等
Try setting CHROME_EXECUTABLE to a Chrome executable
pta a.1003 的收获
Go (二) 函数部分1 -- 函数定义,传参,返回值,作用域,函数类型,defer语句,匿名函数和闭包,panic
A-B数对问题|UPC-Count Interval|洛谷-P1102A-B数对
php连接数据库脚本
Oracle null 有哪些注意事项【面试题】
解决Gradle Download缓慢的百种方法
边缘辅助无人机网络的分层联邦学习
MySQL 慢查询
网卡软中断过高问题优化总结
软件测试 -- 入门 1 软件测试是什么?
Flask,1-2
HoloLens联合发明人:打造理想的全天AR需要解决这些问题
关于semantic-ui的cdn失效问题(怎样通过本地引用semantic-ui)
Go (一) 基础部分2 -- if条件判断,for循环语句
[frp intranet penetration]








