<p>我一直在为基本相同的事情编写代码。现在的目标只是用透明的像素替换白色像素,但是它似乎替换了整个图像,所以在某个地方出现了一个bug……但是它在<code>multiprocessing</code>模块中不再出现错误,所以也许它可以作为一个示例,说明如何加载<code>Queue</code>,然后让你的工作进程处理它!在</p>
<pre><code>from PIL import Image
from multiprocessing import Process, JoinableQueue
from threading import Thread
from time import time
def worker_function(q, new_data):
while True:
# print("Items in queue: {}".format(q.qsize()))
index, pixel = q.get()
if pixel[0] > 240 and pixel[1] > 240 and pixel[2] > 240:
out_pixel = (0, 0, 0, 0)
else:
out_pixel = pixel
new_data[index] = out_pixel
q.task_done()
if __name__ == "__main__":
start = time()
q = JoinableQueue()
my_image = Image.open('InputImage.jpg')
my_image = my_image.convert('RGBA')
datas = list(my_image.getdata())
new_data = [0] * len(datas) # make a blank array the size of our image to fill later
print('putting image into queue')
for count, item in enumerate(datas):
q.put((count, item))
print('starting workers')
worker_count = 50
processes = []
for i in range(worker_count):
p = Process(target=worker_function, args=[q, new_data])
p.daemon = True
p.start()
print('main thread waiting')
q.join()
my_image.putdata(new_data)
my_image.save('output.png', "PNG")
end = time()
print('{:.3f} seconds elapsed'.format(end - start))
</code></pre>
<p>我认为在<code>if __name__ == "__main__"</code>块中“保护”代码是很重要的,否则派生的进程似乎在运行它。在</p>
<h2>更新</h2>
<p>看起来你需要实现一个<code>Manager()</code>(或者可能还有其他我不知道的方法!)。我把代码改成:</p>
^{pr2}$
<p>虽然这似乎不是最快的选择!我相信还有其他方法可以提高速度。我对<code>Thread</code>s执行相同操作的代码看起来非常相似:</p>
<pre><code>from PIL import Image
from threading import Thread
from queue import Queue
import time
start = time.time()
q = Queue()
planeIm = Image.open('InputImage.jpg')
planeIm = planeIm.convert('RGBA')
datas = planeIm.getdata()
new_data = [0] * len(datas)
print('putting image into queue')
for count, item in enumerate(datas):
q.put((count, item))
def worker_function():
while True:
# print("Items in queue: {}".format(q.qsize()))
index, pixel = q.get()
if pixel[0] > 240 and pixel[1] > 240 and pixel[2] > 240:
out_pixel = (0, 0, 0, 0)
else:
out_pixel = pixel
new_data[index] = out_pixel
q.task_done()
print('starting workers')
worker_count = 100
for i in range(worker_count):
t = Thread(target=worker_function)
t.daemon = True
t.start()
print('main thread waiting')
q.join()
print('Queue has been joined')
planeIm.putdata(new_data)
planeIm.save('output.png', "PNG")
end = time.time()
elapsed = end - start
print('{:3.3} seconds elapsed'.format(elapsed))
</code></pre>
<p>但是,处理我的图像需要大约23秒的线程和大约170秒的多处理!!我怀疑这可能是因为启动<code>Process</code>对象所需的更大开销,而且我处理每个像素的算法目前都很简单(只是<code>if pixel[0] > 240 and pixel[1] > 240 and pixel[2] > 240:</code>位),所以我很可能无法获得复杂像素处理算法所能带来的速度提升。还要注意<a href="https://docs.python.org/2/library/multiprocessing.html#sharing-state-between-processes" rel="nofollow noreferrer">multiprocessing documentation</a></p>
<blockquote>
<p>a single manager can be shared by processes on different computers over a network. They are, however, slower than using shared memory.</p>
</blockquote>
<p>这让我相信有更快的选择。在</p>