【发布时间】:2012-09-08 11:53:35
【问题描述】:
动机
我想编写一对程序,其中一个程序读取数据并将其转换为内部格式,另一个程序将内部格式转换为其他格式。作为练习,我想在不使用管道的情况下编写这些程序之间的交互。我更喜欢使用信号和共享内存。
我想要什么
我有程序 A 和 B,A 调用 B。我该怎么做
- 从程序 A 创建一个内存块
- 从程序 A 调用程序 B,为其提供有关在何处找到内存块的信息
- 使用两个程序中的内存块。
更具体地说,A 解码自定义视频格式并将单个未压缩帧放入共享缓冲区。 B 从缓冲区中读取数据并将其编码为输出流。解码器每秒解码高达 100 帧,这大约是 500 MiB/s 的内存流量。管道变得很慢,因为必须经常复制数据并且缓冲区不是很大。
我认为可行的方法
我的想法是使用mmap(NULL,len,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0) 创建一段共享内存。问题是,execve(2) 的联机帮助页指出:
不保留内存映射 (mmap(2))。
那么,我怎样才能与其他程序共享该内存?将这两种功能都放在一个程序中并改用fork 是不是更好?
【问题讨论】:
-
你应该把它作为一个学习练习,但请注意,让事情在共享状态下工作,特别是共享内存,太难了,即使付出高昂的代价也应该避免。无论如何,内存共享可能会更加昂贵。作为一个友好的警告:)
-
@Magnus 你认为应该怎么做?共享状态是未压缩像素数据的两个缓冲区。一个进程解码图像,另一个进程编码。由于 512 字节的缓冲区太小,因此使用管道被证明可以完全消除并行性。
-
这作为一个练习很好,但共享内存通常是一个非常糟糕的主意。您可能会查看更高级别的 IPC,例如套接字、命名管道或零 MQ。
-
大数据并不疯狂。例如,SkypeKit 使用共享内存进行视频传输,因为它提供了高吞吐量而没有其他 IPC 机制的开销。
-
@nneonneo 我添加了一段关于数据大小的段落。
标签: c linux memory-mapping execve