经过很长时间的多处理断管

时间:2014-12-09 10:33:22

标签: python multiprocessing broken-pipe

我使用多处理模型开发了一个爬虫。

使用multiprocessing.Queue存储需要抓取的url-infos,需要解析的页面内容等等;使用multiprocessing.Event控制子进程;使用multiprocessing.Manager.dict存储已爬网URL的哈希值;每个multiprocessing.Manager.dict实例都使用multiprocessing.Lock来控制访问。

所有三个类型参数在所有子进程和父进程之间共享,并且所有参数都在一个类中组织,我使用类的实例将共享参数从父进程传输到子进程。就像: MGR = SyncManager() class Global_Params(): Queue_URL = multiprocessing.Queue() URL_RESULY = MGR.dict() URL_RESULY_Mutex = multiprocessing.Lock() STOP_EVENT = multiprocessing.Event() global_params = Global_Params()

在我自己的超时机制中,我使用process.terminate来停止长时间无法自行停止的进程!

在我的测试用例中,有超过2500个目标站点(有些是非服务的,有些是巨大的)。 按站点在目标站点文件中抓取站点。

在开始时爬行器可以正常工作,但经过很长一段时间(有时8小时,有时2小时,有时甚至是15小时),爬行器爬行的距离超过100(这是不确定的)站点,我&#39 ; ll得到错误信息:" Errno 32断管"

我尝试了以下方法来定位和解决问题:

  1. 网站定位哪个抓取工具断了,然后使用抓取工具分别抓取网站,抓取工作得很好。即使我从包含站点A的所有目标站点文件中获取了一个片段(例如20个站点),但爬虫也运行良好!

  2. 添加" -X / tmp / pymp- * 240 / tmp"到/etc/cron.daily/tmpwatch

  3. 发生破坏时文件/ tmp / pymp- *仍然存在

  4. 使用multiprocessing.managers.SyncManager替换multiprocessing.Manager并忽略除SIGKILL和SIGTERM之外的大多数信号

  5. 对于每个目标站点,我清除了大多数共享参数(队列,dicts和事件),如果发生错误,则创建一个新实例:

  6. while global_params.Queue_url.qsize()>0: try: global_params.Queue_url.get(block=False) except Exception,e: print_info(str(e)) print_info("Clear Queue_url error!") time.sleep(1) global_params.Queue_url = Queue() pass   以下是Traceback信息,print_info函数定义为自己打印和存储调试信息: [Errno 32] Broken pipe Traceback (most recent call last): File "Spider.py", line 613, in <module> main(args) File "Spider.py", line 565, in main spider.start() File "Spider.py", line 367, in start print_info("STATIC_RESULT size:%d" % len(global_params.STATIC_RESULT)) File "<string>", line 2, in __len__ File "/usr/local/python2.7.3/lib/python2.7/multiprocessing/managers.py", line 769, in _callmethod kind, result = conn.recv() EOFError   我无法理解为什么,有人知道原因吗?

1 个答案:

答案 0 :(得分:1)

我不知道这是否可以解决您的问题,但有一点值得一提:

global_params.Queue_url.get(block=False)

...如果队列为空,则抛出Queue.Empty命令。为空例外重新创建队列是不值得的。

重新排队可能会导致竞争条件。

从我的角度来看,你必须有可能:

  1. 摆脱&#34;队列娱乐&#34;代码块
  2. 切换到其他队列实施
  3. 使用:

    from Queue import Queue
    

    而不是:

    from multiprocessing import Queue