从 C++ 启动程序,与管道交换信息,然后共享内存
我目前正在开发一个使用 C 和 C 语言共享内存的模块化框架。 C++。 目标是在 C 和 C++ 中拥有独立的程序,通过共享内存相互通信。
例如,一个程序负责读取 GPS,另一个程序负责处理来自多个传感器的数据。
主程序将启动所有从程序 (目前我正在使用 fp = popen(./slave1/slave1,"r"); 来执行此操作),然后创建每个从属设备可以连接到的共享内存段。 这背后的想法是,如果从设备死亡,它可以被主设备复活并重新连接到相同的共享内存段。
从属设备也可以在运行时进行交换(例如,将一个 GPS 切换到另一个 GPS)。
问题是我通过 popen 生成从属设备,并将共享内存 ID 传递给从属设备。从属设备通过管道传回所需的大小。 完成此操作后,我想将从站的管道重新路由到终端以显示调试消息而不是通过主站。
非常感谢您提出建议以及该问题的其他解决方案。 关键是在设置共享内存之前进行某种形式的通信。
I am currently developing a modular framework using shared memory in C & C++.
The goal is to have independent programs in both C and C++, talk to each other through shared memory.
E.g. one program is responsible for reading a GPS and another responsible for processing the data from several sensors.
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.
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 (e.g. switch one GPS with another).
The problem is that I spawn the slave via popen, and pass the shared memory ID to the 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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我建议用另一种方式来沟通。命名管道是我的想法。重新路由标准输出/错误充其量也是很棘手的。
我建议使用 boost.interprocess 来处理 IPC。并注意同步:)
my2c
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. And be attentive to synchronization :)
my2c
您可能想研究一下 unix 域套接字的 SCM_RIGHTS 传输模式 - 这可以让您通过本地套接字上的文件描述符。这可用于将 stderr 等传递给您的从属进程。
您还可以将共享内存段作为文件描述符传递(至少在 Linux 上)。在
/dev/shm
中创建一个随机名称的文件并立即取消链接。现在ftruncate
到所需的大小并使用MAP_SHARED
mmap
。现在您有一个与文件描述符绑定的共享内存段。这种方法的好处之一是,如果持有共享内存段的所有进程都终止,共享内存段将自动销毁。将它们放在一起,您可以将 unix 域
socketpair()
的一端传递给您的从属设备。只需通过 exec 保持 fd 打开,并在命令行上传递 fd 编号即可。通过套接字对将您想要的任何配置信息作为普通数据传递,然后移交指向共享内存段的文件描述符。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. This can be used to pass stderr and the like to your slave processes.
You can also pass shared memory segments as a file descriptor as well (at least on Linux). Create a file with a random name in
/dev/shm
and unlink it immediately. Nowftruncate
to the desired size andmmap
withMAP_SHARED
. 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()
. Just leave the fd open over exec, and pass the fd number on the command line. 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.管道不可重新路由——它们会移动到创建时所在的位置。您需要做的是让从属设备在完成后关闭管道,然后在其他地方重新打开其标准输出。如果你总是想输出到终端,你可以使用 freopen("/dev/tty", "w", 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.要解决特定问题,请将调试消息发送到 stderr,而不是 stdout。
To address the specific issue, send debug messages to stderr, rather than stdout.