繁体   English   中英

Python 和 C++ 共享相同的内存资源

[英]Python and C++ sharing the same memory resources

假设我们正在使用Python并调用一些用C++编写的DLL库。 我们在 Python 中打开一个非常大的数据集,然后我们想调用一个用 C++ 编写的库,并添加一个以打开的数据作为参数的数组。 库会对该数组做一些事情,然后将它返回给 Python 代码。

所以问题是:是否可以使用内存的相同位置? 因为在那种情况下,我们不需要将大量数据复制两次。

这一切都取决于您如何将数据加载到内存中以及它是什么类型的数据。

如果它是数字数据并且您使用例如 numpy 数组,则它已经存储在可以从 C 或 C++ 代码中轻松使用的内存布局中。 很容易获取数据块的地址( numpy.ndarray.ctypes.data )并通过ctypes传递给C++代码。 你可以在这里看到一个很好的例子。 图像数据在这方面是相似的(PIL 图像采用简单的存储格式,可以轻松获得指向其数据的指针)。

另一方面,如果您的数据是常规的“本机”Python 结构(例如常规列表或常规对象),则情况会更加棘手。 可以将它们直接传递给 C++ 代码,但这些代码必须了解 Python 数据结构——因此,专门为此目的而编写,使用python.h并处理非平凡的 Python API。

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

 $ 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