我是python的新手,对多处理来说肯定是新手。我正在关注this question/answer我的多处理结构,但是在def func_A
中,我正在调用一个模块,它将类对象作为参数之一传递。在模块中,我更改了一个对象属性,我希望主程序看到并使用对象属性值更新用户。子进程运行的时间很长,因此我需要主程序在运行时提供更新。
我的怀疑是我不理解命名空间/对象范围或类似的东西,但是从我读过的内容,将一个对象(一个类的实例?)作为参数传递给一个模块传递一个引用到对象而不是副本。我原以为这意味着更改子进程/模块中对象的属性会改变主程序对象中的属性(因为它们是同一个对象)。或者我混淆了什么?
我的主程序的代码:
# MainProgram.py
import multiprocessing as mp
import time
from time import sleep
import sys
from datetime import datetime
import myModule
MYOBJECTNAMES = ['name1','name2']
class myClass:
def __init__(self, name):
self.name = name
self.value = 0
myObjects = []
for n in MYOBJECTNAMES:
myObjects.append(myClass(n))
def func_A(process_number, queue):
start = datetime.now()
print("Process {} (object: {}) started at {}".format(process_number, myObjects[process_number].name, start))
myModule.Eval(myObjects[process_number])
sys.stdout.flush()
def multiproc_master():
queue = mp.Queue()
proceed = mp.Event()
processes = [mp.Process(target=func_A, args=(x, queue)) for x in range(len(myObjects))]
for p in processes:
p.start()
for i in range(100):
for o in myObjects:
print("In main: Value of {} is {}".format(o.name, o.value))
sleep(10)
for p in processes:
p.join()
if __name__ == '__main__':
split_jobs = multiproc_master()
print(split_jobs)
我的模块程序的代码:
# myModule.py
from time import sleep
def Eval(myObject):
for i in range(100):
myObject.value += 1
print("In module: Value of {} is {}".format(myObject.name, myObject.value))
sleep(5)
答案 0 :(得分:0)
你链接到的question/answer可能是用作模板的不好选择,因为它做了许多你的代码不需要的东西(更少使用)。
我认为您对多处理如何工作的最大误解是认为所有代码都在同一地址空间中运行。主要任务独立运行,每个子任务都有单独的任务。编写代码的方式,每个代码最终会有自己独立的myObjects
列表。这就是为什么主要任务没有看到任何其他任务所做的任何改变。
虽然是方式使用multiprocessing
模块共享对象,但这样做通常会带来很大的开销,因为在所有进程之间保持它或它们都是同步的,需要发生很多事情“在封面下“使看起来就像他们共享一样(这是真正发生的事情,因为他们实际上不能因为拥有单独的地址空间)。这种开销经常完全取消并行处理所获得的任何速度。
如文档中所述:“when doing concurrent programming it is usually best to avoid using shared state as far as possible”。