我正在尝试修改python程序,以便能够使用共享内存与C ++程序进行通信。 python程序的主要职责是从位于共享内存中的输入队列中读取一些视频帧,对视频帧执行某些操作并将其写回共享内存中的输出队列。
我相信我需要做的事情很少,如果有人可以对它有所了解,那就太棒了:
共享内存:在C / C ++中,您可以使用shmget
和shmat
等函数来获取指向共享内存的指针。在python中处理这个问题的等效方法是什么,所以python和C ++程序都可以使用相同的共享内存?
同步:因为这涉及多处理,我们需要在C ++和python程序中为共享内存提供某种锁定机制。我怎么能在python中做到这一点?
非常感谢!
答案 0 :(得分:1)
或许shmget
和shmat
不一定是您使用的最合适的界面。在我工作的项目中,我们使用内存映射文件通过C和Python API提供对守护程序的访问,这为我们提供了一种非常快速的数据访问方式
操作顺序有点像这样:
door_call()
告诉守护进程创建共享内存区域open()
,然后mmap()
该文件door_return()
mmap()
是文件描述符,并将具有该fd的结构中的连续放置的变量关联起来我们的客户使用库来处理上面的前5个步骤;该库附带了使用ctypes的Python包装器,以准确显示所需的函数和数据类型。
对于你的问题空间,如果它只是写入输出队列的python应用程序,那么你可以跟踪python应用程序中已处理的帧。如果你的python和c ++应用程序都写入输出队列,那么这会增加你的难度,也许重构整个应用程序架构将是一个很好的投资。
答案 1 :(得分:1)
Sorta,有点共享内存。因此,OP并非完全如此。
这可以使用内存映射文件进行。我不以任何方式要求高速或高效。这些只是为了展示它工作的示例。
hello_world
C ++端仅监视其所需的值。 Python端仅提供值。
注意:文件名“ pods.txt”在C ++和python代码中必须相同。
.rodata
python端:
$ python --version
Python 3.7.9
$ g++ --version
g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
要在终端#1中运行它,
#include <sys/mman.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(void)
{
// assume file exists
int fd = -1;
if ((fd = open("pods.txt", O_RDWR, 0)) == -1)
{
printf("unable to open pods.txt\n");
return 0;
}
// open the file in shared memory
char* shared = (char*) mmap(NULL, 8, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
// periodically read the file contents
while (true)
{
printf("0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", shared[0], shared[1], shared[2], shared[3], shared[4], shared[5], shared[6], shared[7]);
sleep(1);
}
return 0;
}
即由于C ++代码中的sleep(2),您应该看到0x01每隔几秒钟移动一次。
在2号航站楼:
import mmap
import os
import time
fname = './pods.txt'
if not os.path.isfile(fname):
# create initial file
with open(fname, "w+b") as fd:
fd.write(b'\x01\x00\x00\x00\x00\x00\x00\x00')
# at this point, file exists, so memory map it
with open(fname, "r+b") as fd:
mm = mmap.mmap(fd.fileno(), 8, access=mmap.ACCESS_WRITE, offset=0)
# set one of the pods to true (== 0x01) all the rest to false
posn = 0
while True:
print(f'writing posn:{posn}')
# reset to the start of the file
mm.seek(0)
# write the true/false values, only one is true
for count in range(8):
curr = b'\x01' if count == posn else b'\x00'
mm.write(curr)
# admire the view
time.sleep(2)
# set up for the next position in the next loop
posn = (posn + 1) % 8
mm.close()
fd.close()
即您应该会看到位置从0到7再次变回0。