我发现,如果我通过管道发送派生类型作为引用,则通信派生 C++ 类型(例如 opencv Mat 或其他派生类型)确实会通过管道:
//Measurement FIFO while(1) { Mat xboxobs = some value; //changes in every iteration const char * obsfifo = "/tmp/obsfifo"; mkfifo(obsfifo, 0666); fm = open(obsfifo, O_WRONLY | O_NONBLOCK); write(fm, &xboxobs, 1024 ); close(fm); }
并阅读阅读器中的参考文献,如下所示::
while(1)
{
//READ kalman measurement fifo
const char * obsfifo = "/tmp/obsfifo";
fm = open(obsfifo, O_RDONLY );
Mat xboxobs;
read(fm, &obs, 1024 );
close(fm);
fflush(stdout);
}
unlink(obsfifo);
当我尝试通过使用或Mat xboxobs
打印来访问阅读器中的内容时,出现错误。我正在同一台 Linux 机器上实现读取器和写入器。STDOUT
std::cout
printf
问题1:通常不可能通过命名管道安全地移动派生类型,还是我在这里遗漏了一些东西?
问题2:作为旁路,我通过命名管道将矩阵的每个元素Mat xboxobs
和其他元素Mats
作为浮点数发送,并且我必须通过 中的各个管道与大约 30 个浮点数进行通信/tmp/somefifo
。我总共发送了 30 个浮点数,其中 15 个浮点数来自同时运行的两个单独的 C++ 代码,并且我将这些浮点数聚合回接收器代码中的矩阵中。
好处是,这可行,但我在从每个 fifo 读取数据和在使用矩阵进行其他数学运算之前将矩阵浮点元素组装回矩阵之间的读取时间非常慢(大约 2 ~ 3 秒)。
我还发现,当我在编写器代码中使用 不要使用 O_NONBLOCK 时,当我实现读取器时,程序会冻结。调试并gdb
没有告诉我什么特别的信息,但是当我停止调试过程时,我得到以下信息:
0x00007ffff68ba870 in __write_nocancel () at ../sysdeps/unix/syscall-template.S:81 81 ../sysdeps/unix/syscall-template.S:没有这样的文件或目录。
我不知道为什么在不解锁编写器代码的情况下我似乎无法安全地运行这三个程序。当我在发送之前分割矩阵时,为什么接收器代码如此慢?这正常吗?
我肯定会很感激任何帮助。
答案1
read
并且write
不要引用;他们采取指针。 Prefix-& 是取址运算符,它返回一个指针。它是后缀-& 表示引用。
以这种方式将数据传递给另一个程序能工作,但是仅有的在以下情况下:
- 该类不使用指针,而是将所有内容存储在类本身内部
- 两个程序使用的 C++ ABI 相同(由编译器和 C++ 标准库定义)
- 您的类(以及它使用的任何其他类)的定义在两个程序中都是相同的
- 两个程序以相同的优化级别调用编译器
如果其中之一不是这种情况,那么类中某些数据元素的偏移量很可能会有所不同,然后事情就会发生变化繁荣。如果你幸运的话,它甚至可以做到这一点每一个时间,而不是看似随机的。
将数据传递到另一个程序的更好方法是使用序列化库。有多种可供选择;流行的一个是包含在增强中