我有一个生成进程的主进程,然后这些进程将作业添加到主进程用于生成更多进程的Queue。并且,这可以正常工作大约20秒,然后主进程就会停止产生作业,即使它在队列中有大量的工作。
这是作业流程运行循环的代码:
try:
page = self.fetch_page(self.url, self.timeout)
if page != None:
#do_stuff
pass
except Exception, e: #Log any errors
import traceback
self.log(str(traceback.format_exc(limit=10)), level="error")
self.log(str(e), level="error")
finally:
import os, signal
print "releasing Semaphore"
self.__sem.release()
#print "Joining pQueue" #these statements raise errors...
#self.__pqueue.join_thread()
#print "Joining lQueue"
#self.__log.join_thread()
print "exiting"
os._exit(1)
#os.kill(self.pid, signal.SIGTERM)
这是生成作业的主要流程的代码:
while True:
print "Waiting for url"
url = self.page_queue.get()
print "waiting for semaphore"
self.__sem.acquire()
print "semaphore recived"
process = self.process_handler(url, self.log_queue, self.__sem, self.page_queue)
process.start()
只是一个小的上下文,产生过程中的self.log_queue是自我.__登录作业过程,self.page_queue在作业过程中是自我.__ pqueue,而self .__ sem与作业中的self .__ sem相同过程
水疗过程通常挂在:
url = self.page_queue.get()
我很确定在作业进程在完成写入队列之前终止时,队列中的队列被破坏了,但这只是一种预感。和self .__ pqueue.join_thread()引发一个断言错误。
答案 0 :(得分:1)
不确定这是否有用,但如果你的self.page_queue是Queue的实例(http://docs.python.org/library/queue.html),那么get()默认是阻止的。你确认队列不是空的吗?它可能只是挂着等待一个项目。我记得当我使用队列时困扰着我。
此外,它不会加入,直到你执行get()的每个任务,你已经调用了task_done()
答案 1 :(得分:1)
如果您正在获取网页,则应考虑使用eventlet库而不是多个进程。如果要进行大量计算,拆分成多个进程非常有用。但是,您可能会花费大部分时间等待Internet连接。结果,浪费了启动过程的额外开销。
Eventlet适用于协作线程模型,使编写此类应用程序变得更加容易。
答案 2 :(得分:0)
好的,我修好了。我的第一个预感是队列在写作中被杀死了。但是,在使用Queue.qsize()检查以确保队列中包含值之后,我开始认为这是导致问题的信号量。所以我查看了多处理管理器对象,这些对象允许进程通过“代理”来操纵他们的数据。所以我切换了逻辑,以便所有的Queue和Semaphores都可以被Manager对象控制,而且似乎已经完美地完成了。链接到适用的python文档:http://docs.python.org/library/multiprocessing.html#sharing-state-between-processes