IPC:在两个程序之间的c ++中使用命名管道 [英] IPC: Using of named pipes in c++ between two programs

查看:96
本文介绍了IPC:在两个程序之间的c ++中使用命名管道的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to realise a IPC between two different programs running on the same machine (in my case its a CentOS7). To have just a kind of loose coupling I decided to use a named pipe for the IPC. Therefore I'm was playing with the following example and ran into different problems.

创建并写入管道:

#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分隔).

I feel like named pipes are pretty unflexible in its behavior I figured out with my test programs. First of all if no reading process is attached to the fifo pipe all messages except of the last one written to the pipe get lost (or generally speaking only the last message can be read after the reading process is attached to the pipe). If you write multiple messages into the pipe all messages betweem the reading (e.g. polled) will be interpreted as one single message (I'm aware that they can be splitted by \0).

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

The main goals for the named pipe is a) system logs and b) kind of user authentication. The asynchronous of named pipes fits perfectly to my need. But anyway, I'm not sure if named pipes are the best solution for IPC between different programs. Also I'm not sure if the behavior descripted above is normal or if I'm using named pipe in a wrong way. I also thought about sockets but then I will run into huge blocking problems.

感谢您的帮助.

推荐答案

首先,如果未将读取过程附加到fifo管道,则除最后一个写入管道的消息外,所有消息都会丢失".

"First of all if no reading process is attached to the fifo pipe all messages except of the last one written to the pipe get lost".

不,他们没有.使用cat代替您的(大声写的:D)阅读过程,您将获得所有消息.

No, they don't. Use cat instead of your (lousily written :D) reading process and you'll get all of the messages.

你是对的.管道是面向字节的,而不是面向消息的.如果您需要消息,则可以使用其他IPC(例如SysV消息队列).

You are right. Pipes are byte-oriented, not message oriented. If you want messages, there's other IPC for that (e.g., SysV message queues).

《 Beej Unix IPC指南》 是Unix的出色入门ipc,如果您想要更高级的内容,那么Richard Stevens的 Unix环境中的高级编程很好.

Beej's Guide to Unix IPC is an excellent intro to Unix ipc, if you want something more advanced, then Advanced Programming in the Unix Environment by Richard Stevens is very good.

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

As far as user authentication is concerned, check out Unix sockets.

这篇关于IPC:在两个程序之间的c ++中使用命名管道的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆