当前位置:网站首页>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;
}
边栏推荐
猜你喜欢
随机推荐
亲身分享一次 字节跳动 真实面试经历和面试题
用户登录验证程序的实现
HANA 常用数据类型详解
[CSRF, SSRF, XXE, PHP deserialization, Burpsuite]
arm64麒麟安装paddlehub(国产化)注意事项
Kotlin 中的泛型介绍
Leetcode刷题——128. 最长连续序列
中国水煤浆行业“十四五”规划与运营模式分析报告2022~2028年
spark sql 报错 Can‘t zip RDDs with unequal numbers of partitions
软件测试 -- 入门 1 软件测试是什么?
Haproxy服务监控
Flask,7
Let small program development into ` tailwind jit ` era
【 Nmap and Metasploit common commands 】
MySQL 优化建议详解
寄存器常见指令
MySQL EXPLAIN 性能分析工具详解
Ansible installation and deployment detailed process, basic operation of configuration inventory
【DC-2 Range Penetration】
pta a.1003 的收获