简体   繁体   English

从C ++启动程序,使用管道交换信息,然后共享内存

[英]Starting programs from C++, exchanging info with pipes and then shared memory

I am currently developing a modular framework using shared memory in C & C++. 我目前正在使用C&C ++中的共享内存开发模块化框架。 The goal is to have independent programs in both C and C++, talk to each other through shared memory. 目标是在C和C ++中拥有独立的程序,通过共享内存相互通信。

Eg one program is responsible for reading a GPS and another responsible for processing the data from several sensors. 例如,一个程序负责读取GPS,另一个程序负责处理来自多个传感器的数据。

A master program will start all the slave programs (currently i am using fp = popen(./slave1/slave1,"r"); to do this) and then make shared memory segments that each slave can connect to. 主程序将启动所有从属程序(当前我使用fp = popen(./slave1/slave1,"r");执行此操作)然后创建每个从属可以连接的共享内存段。 The thought behind this is that if a slave dies, it can be revived by the master and reconnect to the same shared memory segment. 这背后的想法是,如果从属设备死亡,它可以由主设备恢复并重新连接到相同的共享内存段。
Slaves can also be exchanged during runtime (eg switch one GPS with another). 也可以在运行期间交换从站(例如,将一个GPS与另一个GPS切换)。

The problem is that I spawn the slave via popen, and pass the shared memory ID to the slave. 问题是我通过popen生成slave,并将共享内存ID传递给slave。 Via the pipe the slave transmits back the size needed. 通过管道,从属设备传回所需的大小。 After this is done i want to reroute the slave's pipe to terminal to display debug messages and not pass through the master. 完成此操作后,我想将从属管道重新路由到终端以显示调试消息,而不是通过主服务器。

Suggestions are greatly appreciated, as well as other solutions to the issue. 非常感谢建议,以及该问题的其他解决方案。 The key is to have some form of communication prior to setting up the shared memory. 关键是在设置共享内存之前进行某种形式的通信。

I suggest to use another mean to communicate. 我建议用另一种方式来沟通。 Named pipe are the way I think. 命名管道是我的想法。 Rerouting standard out/err will be tricky at best. 重新启动标准输出/错误将充其量是棘手的。

I suggest to use boost.interprocess to handle IPC. 我建议使用boost.interprocess来处理IPC。 And be attentive to synchronization :) 并注意同步:)

my2c MY2C

You may want to look into the SCM_RIGHTS transfer mode of unix domain sockets - this lets you pass a file descriptor across a local socket. 您可能希望查看unix域套接字的SCM_RIGHTS传输模式 - 这允许您通过本地套接字传递文件描述符。 This can be used to pass stderr and the like to your slave processes. 这可以用于将stderr等传递给您的从属进程。

You can also pass shared memory segments as a file descriptor as well (at least on Linux). 您也可以将共享内存段作为文件描述符传递(至少在Linux上)。 Create a file with a random name in /dev/shm and unlink it immediately. /dev/shm创建一个随机名称的文件,并立即取消链接。 Now ftruncate to the desired size and mmap with MAP_SHARED . 现在使用MAP_SHARED ftruncate到所需的大小和mmap Now you have a shared memory segment tied to a file descriptor. 现在,您有一个绑定到文件描述符的共享内存段。 One of the nice things about this approach is the shared memory segment is automatically destroyed if all processes holding it terminate. 这种方法的一个好处是共享内存段会自动销毁,如果所有进程都终止它。

Putting this together, you can pass your slaves one end of a unix domain socketpair() . 将它们放在一起,你可以将你的奴隶传递给unix域socketpair()一端。 Just leave the fd open over exec, and pass the fd number on the command line. 只需将fd打开到exec上,然后在命令行中传递fd号。 Pass whatever configuration information you want as normal data over the socket pair, then hand over a file descriptor pointing to your shared memory segment. 通过套接字对传递您想要的任何配置信息作为普通数据,然后移交指向共享内存段的文件描述符。

要解决特定问题,请将调试消息发送到stderr,而不是stdout。

Pipes are not reroutable -- they go where they go when they were created. 管道不可重新铺设 - 它们在创建时就会到达目的地。 What you need to do is have the slave close the pipe when its done with it, and then reopen its stdout elsewhere. 您需要做的是让奴隶在完成管道时关闭管道,然后在其他地方重新打开它的标准。 If you always want output to the terminal, you can use freopen("/dev/tty", "w", stdout) , but then it will always go to the terminal -- you can't redirect it anywhere else. 如果你总是希望输出到终端,你可以使用freopen("/dev/tty", "w", stdout) ,但它总是会转到终端 - 你不能将它重定向到其他地方。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM