我有一个简单的类ImageData,使用Shepard插值创建一些图像。我必须生成超过50个图像,所以我可以并行化这个。我试过这个(我之前从未使用过多处理,所以,对不起,如果我做了些蠢事),已经应用了@Alfe教给我的东西:
class ImageData(object):
def __init__(self, width, height, range_min=-1, range_max=1):
"""
The ImageData constructor
"""
self.width = width
self.height = height
#The values range each pixel can assume
self.range_min = range_min
self.range_max = range_max
self.data = []
for i in range(width):
self.data.append([0] * height)
def shepard_interpolation(self, queue, seeds=10):
"""
Perform a Shepard shepard_interpolation
:param queue
:param seeds
"""
points = []
f = []
for s in range(seeds):
# Generate a pixel position
pos_x = random.randrange(self.width)
pos_y = random.randrange(self.height)
# Save the f(x,y) data
x = Utils.translate_range(pos_x, 0, self.width, self.range_min, self.range_max)
y = Utils.translate_range(pos_y, 0, self.height, self.range_min, self.range_max)
z = Utils.function(x, y)
points.append([x, y])
f.append(z)
for i in range(self.width):
xt = (Utils.translate_range(i, 0, self.width, self.range_min, self.range_max))
for j in range(self.height):
yt = (Utils.translate_range(j, 0, self.height, self.range_min, self.range_max))
self.data[i][j] = Utils.shepard_euclidian(points, f, [xt, yt], 3)
queue.put(self)
if __name__ == '__main__':
q = Queue()
processes = [Process(target=ImageData.shepard_interpolation, args=(ImageData(50, 50), q,)) for _ in range(2)]
for process in processes:
process.start()
for process in processes:
process.join()
print "Finish"
问题是'因为当我调用传球范围(2)时,一切正常,但是当我尝试使用范围(3)时,它永远不会结束(我的代码永远不会达到'完成'打印)并且我不知道为什么。而且,在我的情况下,我必须生成超过50个图像,我不知道如何实现这一点。我有一个处理器Core 2 Duo。
编辑:
我试图评论queue.put(self)
并且它有效。但是我必须收到结果,这是迄今为止我知道的唯一方法来实现这一目标。我也不明白为什么它有两个进程。
关于我能做些什么来解决这个问题的任何想法?我猜错误是在shepard_euclidian
方法中。但直到现在我才找到它。这是这个功能:
def shepard_euclidian(x, z, p, u):
n = len(x)
d = [0.0] * n
for i in range(n-1):
pi = x[i]
d[i] = math.pow(math.hypot(pi[0]-p[0], pi[1]-p[1]), u)
w = [0.0] * n
sw = 0.0
for i in range(n-1):
w[i] = 1.0
for k in range(n-1):
if i != k:
w[i] *= d[k]
sw += w[i]
for i in range(len(w)-1):
if sw != 0.0:
w[i] /= sw
else:
w[i] = 0.0
c = 0.0
for i in range(n):
c += (w[i] * z[i])
return c
当我尝试这个时:
for i in range(self.width):
xt = (Uts.Utils.translate_range(i, 0, self.width, self.range_min, self.range_max))
for j in range(self.height):
yt = (Uts.Utils.translate_range(j, 0, self.height, self.range_min, self.range_max))
data = Uts.Utils.shepard_euclidian(points, f, [xt, yt], 3)
queue.put(data)
有效。但这不是我想要的。
如果我试试这个:
aux = ImageData(50, 50)
for i in range(self.width):
xt = (Uts.Utils.translate_range(i, 0, self.width, self.range_min, self.range_max))
for j in range(self.height):
yt = (Uts.Utils.translate_range(j, 0, self.height, self.range_min, self.range_max))
aux[x][y] = Uts.Utils.shepard_euclidian(points, f, [xt, yt], 3)
self.data = aux
queue.put(self.data)
它不起作用。我真的不知道该怎么做。
任何帮助将不胜感激。 提前谢谢。
答案 0 :(得分:1)
您想要记住所有进程(在您的外观中称为k
丑陋)并在第二个循环中加入所有。也许这解决了你手头的问题。
请使用更好的名字:
processes = [
Process(target=ImageData.shepard_interpolation, args=(ImageData(50, 50), q,))
for _ in range(3) ]
for process in processes:
process.start()
for process in processes:
process.join()
编辑:
我的代码的最小版本在我的机器上没有问题:
import os
from multiprocessing import *
class ImageData(object):
def __init__(self, a, b):
pass
def shepard_interpolation(self, queue, seeds=10):
self.pid = os.getpid()
print self.pid, "queue put"
queue.put(self)
if __name__ == '__main__':
q = Queue()
processes = [ Process(
target=ImageData.shepard_interpolation, args=(ImageData(50, 50), q))
for _ in range(10) ]
for process in processes:
process.start()
results = []
for process in processes: # just to have the correct amount of results
results.append(q.get())
print '---------Out--------'
for process in processes:
process.join()
print [ result.pid for result in results ]