当前位置:网站首页>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;
}
边栏推荐
猜你喜欢

优雅的拦截TabLayout的点击事件

npm run dev/serve 时报错

浏览器中的 preview 和 response 的值不一致

The ` monorepo ` ` hoist ` mechanism lead to the change of the loading configuration file path

EIP-5058 能否防止NFT项目方提桶跑路?

【DC-5靶场渗透】

微信小程序 自定义tabBar

Qlik Sense 聚合函数及范围详解(Sum、Count、All、ToTaL、{1})

MySQL 索引检索原理和B+Tree数据结构详解

陆运信息系统——班列项目总结(一)
随机推荐
【源码解读】火爆的二舅币真的跑路了吗?
Kettle Spoon 安装配置详解
浏览器多线程离屏渲染压缩打包方案
自定义封装组件-国际化-下拉搜索
The result of request.getParameter is on
Playing with Markdown(2) - Extraction and Manipulation of Abstract Syntax Trees
Ansible installation and deployment detailed process, basic operation of configuration inventory
Sqli-labs-master shooting range 1-23 customs clearance detailed tutorial (basic)
Let small program development into ` tailwind jit ` era
Flask,3-6
Haproxy服务监控
小码农的第一篇博客
浏览器中的 preview 和 response 的值不一致
布尔盲注需简化代码
【 Nmap and Metasploit common commands 】
经典论文-ResNet
MySQL 一些函数
嵌入式实验二注意点
A-B数对问题|UPC-Count Interval|洛谷-P1102A-B数对
Execute the mysql script file in the docker mysql container and solve the garbled characters