受到教程multiprocessing factorial的启发,我试图对一个简单的力计算模块进行多处理。 我主要担心的是queue.get功能没有按预期的顺序检索。例如,它不是给出[5,4,3,2,1,0,-1,-2,-3,-4,-5],而是根据不同的处理器给出混乱的输出。 1)如何根据进程调用序列追加队列中的结果?我应该使用游泳池,地图,锁或任何这样的东西吗? 2)如何避免内存同步/覆盖问题?
def mp_worker(istart, iend, x, out_q1, out_q2):
global_N = len(x)
outdict1 = []
outdict2 = []
k = 0
for i in range(istart,iend,1):
temp_FX = 0
temp_FY = 0
for j in range(global_N):
if i != j:
temp_FX = temp_FX + (x[j]-x[i])
temp_FY = temp_FY + (x[j]-x[i])
outdict1.append(temp_FX)
outdict2.append(temp_FY)
k = k + 1
out_q1.put(outdict1)
out_q2.put(outdict2)
def mp_factorizer( nprocs):
x = mem.x
FORCE = mem.FORCE
N = len(FORCE)
out_q1 = multiprocessing.Queue()
out_q2 = multiprocessing.Queue()
chunksize = int(math.ceil(N / float(nprocs)))
procs = []
for i in range(nprocs):
istart = chunksize * i
iend = chunksize * (i + 1)
p = multiprocessing.Process(
target=mp_worker,
args=(istart, iend, x, out_q1, out_q2))
procs.append(p)
p.start()
# Collect all results into a single result dict. We know how many dicts
# with results to expect.
resultdict1 = []
resultdict2 = []
for i in range(nprocs):
resultdict1 = resultdict1 + out_q1.get()
resultdict2 = resultdict2 + out_q2.get()
# Wait for all worker processes to finish
for p in procs:
p.join()
return resultdict1
答案 0 :(得分:1)
项目以工作进程完成的任何顺序添加到队列中。如果你想强制订单,你必须......强制订单; - )
Process
对此并不好。它们的执行本质上是无序的,顺序可能会从一次运行变为另一次运行。
在这种情况下,可能最简单:首先,完全抛弃队列。请改为结束你的mp_worker()
:
return outdict1, outdict2
然后使用Pool
。有几种方法可以使用。最喜欢你已经做过的事情就像:
pool = multiprocessing.Pool(nprocs)
for i in range(nprocs):
istart = chunksize * i
iend = chunksize * (i + 1)
p = pool.apply_async(mp_worker, (istart, iend, x))
procs.append(p)
resultdict1 = []
resultdict2 = []
for p in procs:
t1, t2 = p.get()
resultdict1.extend(t1)
resultdict2.extend(t2)
pool.close()
pool.join()
现在结果以相同的顺序获取,任务被传递出去;订单已经被迫。
注意:从+
切换到.extend()
在逻辑上是不必要的,但是将二次时间(循环迭代次数)操作减少到分摊的线性时间操作。这与多处理无关。 somelist = somelist + anotherlist
始终更好地编码为somelist.extend(anotherlist)
。
在这里猜测为什么"它起作用"在Windows而不是Linux上:从历史上看,Linux上的进程创建比Windows更便宜(Windows在加速其线程方面投入了更多精力)。这使得进程更有可能以与开始时相同的顺序在Windows上结束,此时进程执行大约相同的工作量。但他们肯定可以完成"乱序"在Windows上 太
无论如何,Python在任何一个方面都没有发言权:如果您需要特定订单,则必须强制执行该订单。