gpt4 book ai didi

Python 多处理池/进程结果不一致

转载 作者:太空宇宙 更新时间:2023-11-03 15:29:09 24 4
gpt4 key购买 nike

我的共享字典对象的条目数量不一致。它应该有 500,但大多数测试最终都在 450 到 465 之间。我还尝试使用 mapProcess 而不是 apply_async .

map 稍微好一点,因为共享字典有大约 480 个条目,而不是大约 450 个,但它仍然不一致,并且不是预期的全部 500 个条目。

我也尝试过使用 Process,但这导致我的共享字典中的条目数量最少 - 大约 420 个。

这是使用 apply_async 的完整代码:

import numpy as np
from PIL import Image
from os import listdir
from multiprocessing import Manager, Pool

def processImage(path, d):
image = np.array(Image.open(source + "/" + path))

# Copy lists from shared dictionary since updates don't work otherwise
w = d["width"]
h = d["height"]
w.append(image.shape[0])
h.append(image.shape[1])
d["width"] = w
d["height"] = h

if __name__ == "__main__":
source = "./sample/images"
p = Pool()
m = Manager()
d = m.dict()
d["width"], d["height"] = [], []

for path in listdir(source):
p.apply_async(processImage, (path, d))
p.close()
p.join()

这是使用map的完整代码:

def processImage(obj):
image = np.array(Image.open(source + "/" + obj[1]))

w = obj[0]["width"]
h = obj[0]["height"]
w.append(image.shape[0])
h.append(image.shape[1])
obj[0]["width"] = w
obj[0]["height"] = h

if __name__ == "__main__":
source = "./sample/images"
p = Pool()
m = Manager()
d = m.dict()
d["width"], d["height"] = [], []

p.map(processImage, zip(itertools.repeat(d), listdir(source)))

这是使用Process的完整代码:

def processImage(path, d):
image = np.array(Image.open(source + "/" + path))

w = d["width"]
h = d["height"]
w.append(image.shape[0])
h.append(image.shape[1])
d["width"] = w
d["height"] = h

if __name__ == "__main__":
source = "./sample/images"
p = Pool()
m = Manager()
d = m.dict()
d["width"], d["height"] = [], []

jobs = []
for img in listdir(source):
p = Process(target=processImage, args=(img, d))
p.start()
jobs.append(p)

for j in jobs:
j.join()

最佳答案

这是竞争条件的典型示例。您需要某种同步原语来更新d

考虑以下情况:有两个线程(在您的情况下是子进程)正在执行processImage。首先获取wh,第二次获取wh。首先向两者添加一些内容并将其放回d。第二个线程对其自己的 wh 执行某些操作,这些操作不再考虑第一个线程所做的更改,并将其放回 d 。此时,第一个线程所做的更改将丢失。

要解决这个问题,您需要保护与 d 一起使用的部分代码:

from multiprocessing import Manager, Pool, Lock
...
lock = Lock()
...
def processImage(path, d):
image = np.array(Image.open(source + "/" + path))

lock.acquire()
d["width"].append(image.shape[0])
d["height"].append(image.shape[1])
lock.release()

关于Python 多处理池/进程结果不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43011853/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com