我尝试了一些多进程示例,主要是:http://toastdriven.com/blog/2008/nov/11/brief-introduction-multiprocessing/我采用了"简单应用程序",它使用多进程来测试URL。当我使用它(在Python 3.3中,在Windows的PyCharm IDE中)时,经过一些修改,有很多URL,我的脚本从未停止过,我不明白为什么。
import httplib2
import sys
from multiprocessing import Lock, Process, Queue, current_process
def worker(work_queue, done_queue):
for url in iter(work_queue.get, 'STOP'):
try:
print("In : %s - %s." % (current_process().name, url))
status_code = print_site_status(url)
done_queue.put("%s - %s got %s." % (current_process().name, url, status_code))
except:
done_queue.put("%s failed on %s with: %s" % (current_process().name, url, str(sys.exc_info()[0])))
print("Out : %s " % (current_process().name))
return True
def print_site_status(url):
http = httplib2.Http(timeout=10)
headers, content = http.request(url)
return headers.get('status', 'no response')
def main():
workers = 8
work_queue = Queue()
done_queue = Queue()
processes = []
with open("Annu.txt") as f: # file with URLs
lines = f.read().splitlines()
for surl in lines:
work_queue.put(surl)
for w in range(workers):
p = Process(target=worker, args=(work_queue, done_queue))
p.start()
processes.append(p)
work_queue.put('STOP')
for p in processes:
p.join()
print("END")
done_queue.put('STOP')
for status in iter(done_queue.get, 'STOP'):
print(status)
if __name__ == '__main__':
main()
我可以很好地看到测试的所有URL状态,以及指示进程结束的所有进程"Out"消息,但从来没有看到我的"end"消息。我使用的URL列表是:http://www.pastebin.ca/2946850。
所以。。。我的错误在哪里?这是重复的吗:Python多处理线程在完成大量工作时从不连接?
一些信息:当我在代码中处处抑制"done_queue"时:它是有效的。
来自Queue
文档:
如果可选args块为true,超时为None(默认值),则在必要时进行块,直到项目可用。
这意味着你的循环永远不会终止。
如果收到Empty
异常,则需要向get
添加超时并停止循环,或者在收到STOP
消息时需要退出循环。
好吧,我找到了答案(在Python文档中:https://docs.python.org/3.4/library/multiprocessing.html#multiprocessing-编程):
警告如上所述,如果子进程已将项目放在队列(并且它没有使用JoinableQueue.cancel_join_thread),则直到所有缓冲项都被冲洗至管道。
所以更改代码:
print("Out : %s " % (current_process().name))
return True
签字人:
print("Out : %s " % (current_process().name))
done_queue.cancel_join_thread()
return True
我不明白为什么初始代码适用于少量的URL。。。