当前位置: 首页 > 知识库问答 >
问题:

在不同进程之间共享内存中的复杂python对象

皇甫文乐
2023-03-14
    null

共有1个答案

终祯
2023-03-14

对于复杂的对象,没有现成的方法在进程之间直接共享内存。如果您有简单的ctypes,您可以在C样式的共享内存中执行此操作,但它不会直接映射到python对象。

如果您在任何时候只需要一部分数据,而不是整个36GB数据,那么有一个简单的解决方案可以很好地工作。为此,可以使用multiprocessing.managers中的syncmanager。使用该方法,您可以设置一个服务器,为您的数据提供代理类(您的数据不存储在类中,代理只提供对它的访问)。然后,客户机使用baseManager连接到服务器,并调用代理类中的方法来检索数据。

在幕后,Manager类负责处理您所要求的数据,并通过开放端口将其从服务器发送到客户机。因为每次调用都要处理数据,如果需要整个数据集,这样做效率就不高了。在客户机中只需要一小部分数据的情况下,该方法节省了大量时间,因为服务器只需要加载一次数据。

服务器

#!/usr/bin/python
import  sys
from    multiprocessing.managers import SyncManager
import  numpy

# Global for storing the data to be served
gVectors = {}

# Proxy class to be shared with different processes
# Don't but the big vector data in here since that will force it to 
# be piped to the other process when instantiated there, instead just
# return the global vector data, from this process, when requested.
class GloVeProxy(object):
    def __init__(self):
        pass

    def getNVectors(self):
        global gVectors
        return len(gVectors)

    def getEmpty(self):
        global gVectors
        return numpy.zeros_like(gVectors.values()[0])

    def getVector(self, word, default=None):
        global gVectors
        return gVectors.get(word, default)

# Class to encapsulate the server functionality
class GloVeServer(object):
    def __init__(self, port, fname):
        self.port = port
        self.load(fname)

    # Load the vectors into gVectors (global)
    @staticmethod
    def load(filename):
        global gVectors
        f = open(filename, 'r')
        for line in f:
            vals = line.rstrip().split(' ')
            gVectors[vals[0]] = numpy.array(vals[1:]).astype('float32')

    # Run the server
    def run(self):
        class myManager(SyncManager): pass  
        myManager.register('GloVeProxy', GloVeProxy)
        mgr = myManager(address=('', self.port), authkey='GloVeProxy01')
        server = mgr.get_server()
        server.serve_forever()

if __name__ == '__main__':
    port  = 5010
    fname = '/mnt/raid/Data/Misc/GloVe/WikiGiga/glove.6B.50d.txt'

    print 'Loading vector data'
    gs = GloVeServer(port, fname)

    print 'Serving data. Press <ctrl>-c to stop.'
    gs.run()

客户

from   multiprocessing.managers import BaseManager
import psutil   #3rd party module for process info (not strictly required)

# Grab the shared proxy class.  All methods in that class will be availble here
class GloVeClient(object):
    def __init__(self, port):
        assert self._checkForProcess('GloVeServer.py'), 'Must have GloVeServer running'
        class myManager(BaseManager): pass
        myManager.register('GloVeProxy')
        self.mgr = myManager(address=('localhost', port), authkey='GloVeProxy01')
        self.mgr.connect()
        self.glove = self.mgr.GloVeProxy()

    # Return the instance of the proxy class
    @staticmethod
    def getGloVe(port):
        return GloVeClient(port).glove

    # Verify the server is running
    @staticmethod
    def _checkForProcess(name):
        for proc in psutil.process_iter():
            if proc.name() == name:
                return True
        return False

if __name__ == '__main__':
    port = 5010
    glove = GloVeClient.getGloVe(port)

    for word in ['test', 'cat', '123456']:
        print('%s = %s' % (word, glove.getVector(word)))

请注意,psutil库只是用来检查服务器是否运行,而不是必需的。确保将服务器命名为gloveserver.py或更改html" target="_blank">代码中的检查bypsutil,以便查找正确的名称。

 类似资料:
  • 问题内容: 我有以下问题。我编写了一个函数,该函数将列表作为输入并为列表中的每个元素创建一个字典。然后,我想将此字典追加到新列表中,以便获得字典列表。我正在尝试为此生成多个进程。我在这里的问题是,我希望不同的进程访问字典列表,因为它由其他进程更新,例如,一旦达到一定长度,就打印一些东西。 我的例子是这样的: 现在我的问题是每个过程都创建自己的过程。有没有一种方法可以在进程之间共享列表,以便所有字典

  • 问题内容: 我正在尝试使用部分函数,​​以便pool.map()可以定位具有多个参数(在本例中为Lock()对象)的函数。 这是示例代码(摘自我之前的问题的答案): 但是,当我运行此代码时,出现错误: 我在这里想念什么?如何在子流程之间共享锁? 问题答案: 您不能将普通对象传递给方法,因为它们不能被腌制。有两种方法可以解决此问题。一种是创建并传递一个: 不过,这有点重量级;使用需要产生另一个进程来

  • 问题内容: 我在Linux 2.6中。我有一个环境,其中2个进程通过消息传递模式的简单实现来模拟(使用共享内存)数据交换。 我有一个客户端进程(从父进程(即服务器)派生),该进程将struct(消息)写入使用以下命令创建的内存映射区域(在派生之后): 然后将此指针以链接列表的形式写入到另一个共享内存区域中的队列中,该共享内存区域对于服务器和客户端进程是通用的(因为如果在派生之前使用上面的相同代码创

  • 问题内容: 我知道如何将其用于创建共享对象,尤其是可以在工作人员之间共享的队列。有这个问题,这个问题,[这个问题](http://codingdict.com/questions/1299甚至是我自己的一个问题。 但是,我需要定义很多队列,每个队列都链接一对特定的进程。假设每对进程及其链接队列均由变量标识。 当我需要放置和获取数据时,我想使用字典来访问我的队列。我无法完成这项工作。我已经尝试了很多

  • 问题内容: 通过回答此问题,可以回答所有其他三个问题。希望我能说清楚: 在通过多处理创建的某些过程中创建对象后: 如何将对该对象的 引用 传递给其他进程? (不是很重要)我如何确保持有参考书时此过程不会消失? 示例1(已解决) 例子2 假设返回一个具有可变状态的对象。这个相同的对象应该可以从其他进程访问。 例子3 我有一个带有打开文件和锁的对象-如何授予对其他进程的访问权限? 提醒 我不希望此特定

  • 我想在多个python进程之间共享。以便从其他python进程发送。 如何跨多个python进程共享。 代码如下: 目标是从通道从其他python进程发送。