我需要在python中的几个进程之间共享一个对象及其方法.我正在尝试使用Managers(在模块多处理中)但它崩溃了.这是生产者 - 消费者的一个愚蠢的例子,其中两个进程之间的共享对象只是一个包含四种方法的数字列表.
from multiprocessing import Process, Condition, Lock
from multiprocessing.managers import BaseManager
import time, os
lock = Lock()
waitC = Condition(lock)
waitP = Condition(lock)
class numeri(object):
def __init__(self):
self.nl = []
def getLen(self):
return len(self.nl)
def stampa(self):
print self.nl
def appendi(self, x):
self.nl.append(x)
def svuota(self):
for i in range(len(self.nl)):
del self.nl[0]
class numManager(BaseManager):
pass
numManager.register('numeri', numeri, exposed = ['getLen', 'appendi', 'svuota', 'stampa'])
def consume(waitC, waitP, listaNumeri):
lock.acquire()
if (listaNumeri.getLen() == 0):
waitC.wait()
listaNumeri.stampa()
listaNumeri.svuota()
waitP.notify()
lock.release()
def produce(waitC, waitP, …Run Code Online (Sandbox Code Playgroud) 我正在从事一个研究项目,并希望应用并行化来提高执行速度。我之前曾与multiprocessing图书馆合作过,但仅用于数字运算。我将尝试简要描述我的设置和目标。我主要希望来自对多处理概念更有经验的人的想法。
该项目:
该项目是一个多回声供应链模拟(一个多级分销网络),其中根据传入的需求在每个位置定期做出重新订购决策。一个玩具示例如下所示:
Level 3 Level 2 Level 1 Level 0
--- Local Warehouse 1
|
--- Central Warehouse 1 --
| |
| --- Local Warehouse 2
|
Supplier -- Customer
| --- Local Warehouse 3
| |
--- Central Warehouse 2 --
|
--- Local Warehouse 4
Run Code Online (Sandbox Code Playgroud)
模拟对象(简化)如下:
class Simulation:
self.locations = dict() #List of locations
self.customer = Customer() #Object periodically ordering at deepest level (Local) Warehouses
self.levels = {0: [], 1:[],..} # Locations by depth …Run Code Online (Sandbox Code Playgroud) 我有一个在大型图形结构上运行的算法,我想使其成为多线程以获得更好的性能。我看过的方法都不太符合我想要的:我希望图表存在于所有进程都可以读取和写入的共享内存中(使用锁来防止竞争条件)。本质上,我想要像 C 语言中的 OpenMP 一样的东西,其中所有内存都可以由每个线程访问。
我首先查看了线程模块,但 GIL 意味着性能提升微不足道。
我继续尝试多处理模块,正如我在该主题上找到的大多数帖子所建议的那样(例如,如何在多个进程之间共享字典?以及python multiprocessing 中的共享内存对象)。这有两个主要问题。
首先,多重处理似乎不适用于复杂的对象。考虑以下玩具问题:我有一个整数列表,想要将它们全部乘以 10,然后以任意顺序输出所有数字。我可以使用以下代码:
def multiply_list():
manager = Manager()
output = manager.list()
threads = []
for v in range(10):
output.append(v)
print([str(v) for v in output])
def process(inputs, start, end):
while start < end:
inputs[start] *= 10
start += 1
t1 = Process(target=process,
args = (output, 0, 5))
t2 = Process(target=process,
args = (output, 5, 10))
t1.start()
t2.start()
t1.join()
t2.join()
print([str(v) for v in output])
Run Code Online (Sandbox Code Playgroud)
与输出:
['0', '1', …Run Code Online (Sandbox Code Playgroud) 我在程序开始时设置了numpy随机种子.在程序执行期间,我使用多次运行函数multiprocessing.Process.该函数使用numpy随机函数绘制随机数.问题是Process获取当前环境的副本.因此,每个进程都独立运行,它们都以与父环境相同的随机种子开始.
所以我的问题是如何在子环境中与父进程环境共享numpy的随机状态?请注意,我想Process用于我的工作,需要使用一个单独的类,并分别import numpy在该类中执行.我尝试使用multiprocessing.Manager共享随机状态,但似乎事情没有按预期工作,我总是得到相同的结果.此外,如果我将for循环移动到内部drawNumpySamples或将其留在其中并不重要main.py; 我仍然无法得到不同的数字,随机状态总是一样的.这是我的代码的简化版本:
# randomClass.py
import numpy as np
class myClass(self):
def __init__(self, randomSt):
print ('setup the object')
np.random.set_state(randomSt)
def drawNumpySamples(self, idx)
np.random.uniform()
Run Code Online (Sandbox Code Playgroud)
并在主文件中:
# main.py
import numpy as np
from multiprocessing import Process, Manager
from randomClass import myClass
np.random.seed(1) # set random seed
mng = Manager()
randomState = mng.list(np.random.get_state())
myC = myClass(randomSt = randomState)
for i in range(10):
myC.drawNumpySamples() # this will …Run Code Online (Sandbox Code Playgroud)