IPC:在两个程序之间使用 C++ 中的命名管道

2024-06-24

我试图在同一台机器上运行的两个不同程序之间实现IPC(在我的例子中是CentOS7)。为了实现一种松散耦合,我决定对 IPC 使用命名管道。因此,我正在使用以下示例并遇到了不同的问题。

创建并写入管道:

#include <sys/types.h>
#include <sys/select.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>

using namespace std;

main()  {
 int fd;
 char * myfifo = new char [12];
 strcpy(myfifo, "./tmp/myfifo1");

 /* create the FIFO (named pipe) */
 mkfifo(myfifo, 0666);
 /* write "Hi" to the FIFO */
 fd = open("./tmp/myfifo1", O_WRONLY ); //open(myfifo, O_WRONLY | O_NONBLOCK);
 if (fd == -1) {
     perror("open");
     return EXIT_FAILURE;
 } 
 printf("File open\n");
 write(fd, "entry [1]", sizeof("entry [1]"));
 sleep(1);
 write(fd, "entry [2]", sizeof("entry [2]"));
 sleep(2);
 write(fd, "entry [3]", sizeof("entry [3]"));
 printf("Content written\n");
 close(fd);
 printf("Connection closed\n");
 /* remove the FIFO */
 unlink(myfifo);
 return 0;
}

读取管道:

#include <sys/types.h>
#include <sys/select.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <string>
#include <iostream>

using namespace std;

main()  {
 int fd; 
 fd_set set_a;

 char * myfifo = new char [12];
 strcpy(myfifo, "./tmp/myfifo1");
 char buffer[1024];

 fd = open("./tmp/myfifo1", O_RDONLY | O_NONBLOCK);
 if (fd == -1) {
     perror("open");
     return EXIT_FAILURE;
 } 
 ssize_t bytes;
 size_t total_bytes = 0;
 printf("\nDropped into read pipe\n");
 while(1){
     if((bytes = read(fd, buffer, sizeof(buffer))) > 0){
         std::string message(&buffer[22]);
         total_bytes += (size_t)bytes;
         printf("%i", bytes);

         printf("Message: %s\n", message.c_str());
         memset(&buffer[0], 0, sizeof(buffer));
     }else{
         if (errno == EWOULDBLOCK) {
             printf("\ndone reading (%d bytes)\n", (int)total_bytes);
             //break;
         }
         printf("No message\n");
         sleep(2);
     } 
 }
 return EXIT_SUCCESS;
}

我觉得命名管道的行为非常不灵活,这是我通过测试程序发现的。首先,如果没有读取进程附加到 fifo 管道,则除了写入管道的最后一条消息之外的所有消息都会丢失(或者一般来说,在读取进程附加到管道后只能读取最后一条消息)。如果您将多条消息写入管道,则读取之间的所有消息(例如轮询)将被解释为一条消息(我知道它们可以被 \0 分割)。

命名管道的主要目标是a)系统日志和b)用户身份验证。命名管道的异步非常适合我的需要。但无论如何,我不确定命名管道是否是不同程序之间 IPC 的最佳解决方案。另外,我不确定上述行为是否正常,或者我是否以错误的方式使用命名管道。我也考虑过套接字,但随后我会遇到巨大的阻塞问题。

感谢您的帮助。


“首先,如果没有读取进程附加到 fifo 管道,则除了最后写入管道的消息之外的所有消息都会丢失”。

不,他们没有。使用cat而不是你的(写得很糟糕:D)阅读过程,你会得到所有的消息。

你是对的。管道是面向字节的,而不是面向消息的。如果您需要消息,还有其他 IPC(例如 SysV 消息队列)。

Beej 的 Unix IPC 指南 http://beej.us/guide/bgipc/html/single/bgipc.html是 Unix ipc 的一个很好的介绍,如果你想要更高级的东西,那么Unix 环境中的高级编程理查德·史蒂文斯写的非常好。

就用户身份验证而言,请查看 Unix 套接字。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

IPC:在两个程序之间使用 C++ 中的命名管道 的相关文章

  • Linux 上的 JavaFX

    Linux x86 和 x64 上的 JavaFX 情况如何 JavaFX 应用程序可以在 Linux 操作系统上顺利执行吗 我发现了 2011 年和 2012 年的一些问题 当时应用程序不稳定 目前发布的 JFX 版本是 2 2 4 在
  • 在 2 个 .c 文件之间共享函数

    dir1有dir2 file1 c和file1 h dir2 有 file2 c 现在 如果我想在 file2 c 中访问 file1 c 中定义的函数 我需要在 file1 h 中声明它并在 file2 c 中包含 file1 h 这是一
  • 在异步方法中使用时 HttpClient 标头被清空

    我正在使用 NET Framework 4 6 1 我的 Web api 中有一个控制器 其中有静态 HttpClient 来处理所有 http 请求 在 IIS 上托管我的应用程序后 大约每月一次 我的应用程序的所有传入请求都会出现以下异
  • 外部剃刀视图看不到外部模型

    我对外部剃刀视图有疑问 在我的项目中 我有主 mvc Web 程序集和动态加载的外部类库程序集 来自 DB 及其自己的控制器 视图和模型 这些程序集在运行时不会直接引用和加载 我能够通过为控制器创建自定义控制器工厂 为视图创建自定义虚拟路径
  • 用 C# 中的字典中的值替换字符串中的单词

    我有一个简单的dictionary像这样 var fruitDictionary new Dictionary
  • 多态性中基类缺少虚拟析构函数 = 资源泄漏?

    我们知道 如果要多态地使用基类 则需要将基类的析构函数指定为 virtual 否则程序中可能会出现资源泄漏 因为只会调用基类析构函数 而不会调用派生对象析构函数 我们还知道构造函数 析构函数纯粹是初始化 未初始化构造 而operator n
  • 错误 C2065:'cout':未声明的标识符

    我正在处理我的编程作业的 驱动程序 部分 但我不断收到这个荒谬的错误 错误 C2065 cout 未声明的标识符 我什至尝试过使用std cout但我收到另一个错误 IntelliSense 命名空间 std 没有成员 cout 当我宣布u
  • 如何处理作为参数传递到方法中的 Lambda 表达式 - C# .NET 3.5

    我对 Lambda 表达式的了解有点不稳定 虽然我可以编写使用 Lambda 表达式 又名 LINQ 的代码 但我正在尝试编写自己的方法 该方法采用一些 Lambda 表达式类型的参数 背景 我正在尝试编写一个方法 该方法从任何其他对象类型
  • 如果 .txt 文件不存在,则创建一个,如果存在则追加新行

    我想创建一个 txt 文件并写入它 如果该文件已经存在 我只想添加更多行 string path E AppServ Example txt if File Exists path File Create path TextWriter t
  • Excel 2007 中的数值 - 底层 xml 文件中的表示与存储

    这个问题与 NET和OpenXml有关 我已经阅读了以下文章 它有很好的解释 但没有回答我的问题 Excel 2007 中数值的可视化与底层 xml 文件不一致 https stackoverflow com questions 58594
  • 剥离 OLE 标头信息 (MS Access / SQL Server)

    我有一个 C 应用程序需要支持二进制数据库内容 图像等 当使用 MS Access 或 MS SQL Server 时 此数据被包装在 OLE 对象内 如何去除此 OLE 标头信息 请注意 我不能只查找特定标签的开头 因为内容可以是 png
  • 如何检查 Linux 控制台屏幕保护程序是否黑屏

    有没有办法以编程方式 通过 ioctl 等 或通过读取 sys proc 或 dev 中的文件 检查屏幕是否已被 Linux 控制台屏幕保护程序清空 谢谢并致以最诚挚的问候 G nter 好的 检查了 相关代码部分是 include
  • 链接错误:xxx 已在 *****.LIB 中定义:: 究竟出了什么问题?

    Problem 我正在尝试使用一个名为DCMTK http dicom offis de dcmtk它使用了一些其他外部库 zlib libtiff libpng libxml2 libiconv 我已经从同一网站下载了这些外部库 LIB
  • Subsonic 3 ActiveRecord 嵌套选择导致 NotIn 错误?

    我有以下 Subsonic 3 0 查询 其中包含嵌套的 NotIn 查询 public List
  • 是否可以在 Eclipse 中为除 Java 之外的 Eclipse 编写插件?

    谁能帮我用c 写一个eclipse插件 weekens 和 celavek 感谢您提供的信息 我正在研究 JNI 并将尝试实现它 celavek 我们必须做什么样的主控 控制 在C 和java接口中处理是否风险更大 我的要求是在 Java
  • PC 上 XNA 中的信箱和缩放

    有没有一种方法可以让我基本上以 1080p 或 720p 作为默认分辨率来开发 XNA 游戏 然后根据设置的分辨率将游戏中的所有内容缩放到适当的大小 而不必在每个 Sprite 中设置缩放因子Draw 方法 我的想法是 我可以基于 1080
  • 64 位随机生成器种子

    我目前正在运行一个具有 8 个以上管道 线程 的多线程模拟应用程序 这些管道运行非常复杂的代码 该代码取决于种子生成的随机序列 然后该序列被归结为单个 0 1 我希望在将种子从主线程传递到处理管道后 这种 随机处理 具有 100 的确定性
  • 具有可导出私钥的证书的“错误密钥”例外

    我正在尝试使用非对称加密来加密然后解密文件 我已经使用 makecert 创建了一个测试证书并将其安装到我的个人本地计算机存储中 将来我必须在多个服务器上安装此证书 这就是为什么我使用 pe 标志创建它 即使用可导出的私钥 证书已成功创建并
  • RC4 实现与 openssl 输出不匹配

    我的目标是在 C C 中实现 RC4 流密码 并确保它产生与使用时相同的输出openssl命令 按照伪代码维基百科 https en wikipedia org wiki RC4 该实现似乎有效 因为它可以加密和解密内容 但是 加密的输出与
  • Json.net 将数字属性序列化为字符串

    我正在使用 JsonConvert SerializeObject 序列化模型对象 服务器期望所有字段都是字符串 我的模型对象具有数字属性和字符串属性 我无法向模型对象添加属性 有没有办法将所有属性值序列化为字符串 我必须只支持序列化 而不

随机推荐