首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在python和C/C++中使用共享内存

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

Stack Overflow用户
提问于 2018-03-05 04:57:21
回答 2查看 9.8K关注 0票数 15

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

我相信我几乎没有什么需要去实现的,如果有人能给我一些启示,那就太好了:

  1. 共享内存:在C/C++中,您可以使用shmgetshmat等函数来获取指向共享内存的指针。在python中处理此问题的等效方法是什么,以便python和C++程序都可以使用相同的共享内存?
  2. Synchronization:,因为这涉及多个处理,所以在C++和python程序中,我们都需要某种共享内存的锁定机制。我怎么能在蟒蛇身上做到这一点呢?

非常感谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-05 19:31:32

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

操作顺序是这样的:

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

我们的客户端使用一个库来处理上面的前5个步骤;这个库附带Python包装器,使用ctype来公开确切需要哪些函数和数据类型。

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

票数 8
EN

Stack Overflow用户

发布于 2020-12-06 05:12:01

某种程度上是共享的记忆。所以不完全是OP想要的。

此操作使用内存映射文件。我不主张任何方式的高速或高效。这些仅仅是为了展示它起作用的一个例子。

代码语言:javascript
复制
 $ python --version
 Python 3.7.9

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

C++端只监视它需要的值。Python端只提供这些值。

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

代码语言:javascript
复制
#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;
   }

蟒蛇的一面:

代码语言:javascript
复制
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中:

代码语言:javascript
复制
 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++代码中的睡眠(2),您应该看到0x01每隔几秒钟移动一步。

在2号航站楼:

代码语言:javascript
复制
python my.py  # or whatever you called the python file
writing posn:0
writing posn:1
writing posn:2

也就是说,您应该再次看到从0到7的位置变化到0。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49103709

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档