Python 2.7: 线程挂起,不知道如何调试。

1 投票
2 回答
2563 浏览
提问于 2025-04-17 18:04

我写了一个脚本来下载壁纸,这是我学习的一个练习,目的是更好地熟悉Python和线程。整体运行得很顺利,只有在请求一个网址时出现异常。这是我遇到异常的函数(这不是同一个类的方法,如果这有关系的话)。

def open_url(url):
  """Opens URL and returns html"""
  try:
    response = urllib2.urlopen(url)
    link = response.geturl()
    html = response.read()
    response.close()
    return(html)
  except urllib2.URLError, e:
    if hasattr(e, 'reason'):
      logging.debug('failed to reach a server.')
      logging.debug('Reason: %s', e.reason)
      logging.debug(url)
      return None
    elif hasattr(e, 'code'):
      logging.debug('The server couldn\'t fulfill the request.')
      logging.debug('Code: %s', e.reason)
      logging.debug(url)      
      return None
    else:
      logging.debug('Shit fucked up2')      
      return None    

在我脚本的最后:

  main_thread = threading.currentThread()
  for thread in threading.enumerate():
    if thread is main_thread: continue
    while thread.isAlive():
      thread.join(2)      
  break

根据我目前的理解(可能不太对),如果线程在达到这个点后2秒内没有完成任务,它应该会超时。但实际上,它会一直停留在最后的循环里。如果我把这个循环去掉,脚本执行完后就会卡住。

另外,我决定是时候放弃Notepad++,换一个真正的集成开发环境(IDE),带有调试工具,所以我下载了Wing。我非常喜欢Wing,但脚本在那儿并不会卡住……你们都用什么来写Python呢?

2 个回答

0

在Python中,没有线程中断的功能,也就是说你不能直接取消一个线程。线程只能自己完成任务。join这个方法只是让主程序等2秒钟,或者等线程结束,但它并不会强行停止任何东西。如果你想让线程有个超时机制,你需要在线程内部自己实现。

0

我查阅了一些资料,弄明白了怎么解决我遇到的问题。我成功地把脚本快结束时的那段代码完全去掉了。我通过不同的方式来创建线程池,解决了这个问题。

for i in range(queue.qsize()):
  td = ThreadDownload(queue)
  td.start()
queue.join()

而且,在线程执行的时候,我也没有使用 try: 来处理 queue.get()

  try:
    img_url = self.queue.get()
     ...
  except Queue.Empty:
     ...

撰写回答