繁体   English   中英

如何在python和C/C++中使用共享内存

[英]How to use shared memory in python and C/C++

我正在尝试修改一个 python 程序,以便能够使用共享内存与 C++ 程序进行通信。 python 程序的主要职责是从位于共享内存中的输入队列中读取一些视频帧,对视频帧执行一些操作并将其写回共享内存中的输出队列。

我相信我需要完成的事情很少,如果有人能对此有所了解,那就太好了:

  1. 共享内存:在 C/C++ 中,您可以使用shmgetshmat等函数来获取指向共享内存的指针。 在 python 中处理这个问题的等效方法是什么,以便 python 和 C++ 程序可以使用同一块共享内存?

  2. 同步:因为这涉及多处理,所以我们需要在 C++ 和 python 程序中为共享内存提供某种锁定机制。 我怎么能在python中做到这一点?

非常感谢!

也许shmgetshmat不一定是最适合您使用的接口。 在我从事的一个项目中,我们使用内存映射文件通过 C 和 Python API 提供对守护程序的访问,这为我们提供了一种非常快速的数据访问方式

操作顺序有点像这样:

  • 客户端door_call()来告诉守护进程创建一个共享内存区域
  • 守护进程安全地创建一个临时文件
  • 守护进程open() s 然后mmap() s那个文件
  • 守护进程通过door_return()将文件描述符传递回客户端
  • 客户端mmap()是文件描述符,并将结构中连续放置的变量与该 fd 相关联
  • 客户端在这些变量上执行它需要的任何操作 - 当它需要这样做时。
  • 守护进程从共享区域读取并进行自己的更新(在我们的例子中,将值从共享区域写入日志文件)。

我们的客户使用库来处理上述前 5 个步骤; 该库带有 Python 包装器,使用 ctypes 来准确公开需要哪些函数和数据类型。

对于您的问题空间,如果它只是写入输出队列的 python 应用程序,那么您可以跟踪仅在 python 应用程序中处理了哪些帧。 如果您的 Python 和 C++ 应用程序都在写入输出队列,那么这会增加您的难度,也许重构整个应用程序架构将是一项不错的投资。

Sorta,有点共享内存。 所以不完全是 OP 想要的。

这使用内存映射文件。 我不以任何方式声称高速或高效。 这些只是为了展示它的工作示例。

 $ python --version
 Python 3.7.9

 $ g++ --version
 g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0

C++ 端只监控它需要的值。 Python 端只提供值。

注意:C++和python代码中的文件名“pods.txt”必须相同。

#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;
   }

蟒蛇方面:

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()

要运行它,请在终端 #1 中:

 a.out  # or whatever you called the C++ executable
 0x00 0x00 0x00 0x00 0x01 0x00 0x00 0x00
 0x00 0x00 0x00 0x00 0x01 0x00 0x00 0x00
 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00
 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00
 0x00 0x01 0x00 0x00 0x00 0x00 0x00 0x00
 0x00 0x01 0x00 0x00 0x00 0x00 0x00 0x00
 0x00 0x00 0x01 0x00 0x00 0x00 0x00 0x00
 0x00 0x00 0x01 0x00 0x00 0x00 0x00 0x00
 0x00 0x00 0x00 0x01 0x00 0x00 0x00 0x00

即,由于 C++ 代码中的 sleep(2),您应该看到 0x01 每隔几秒移动一步。

在终端#2:

python my.py  # or whatever you called the python file
writing posn:0
writing posn:1
writing posn:2

即您应该看到位置从 0 到 7 再次变回 0。

暂无
暂无

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

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