py2exe打包多线程脚本出错的解决方法
今天用urllib2写了一个多线程爬虫程序,在python环境下解释运行没有问题,但用py2exe打包后执行却出现错误。返回

Exception in thread Thread-1 (most likely raised during interpreter shutdown):
Traceback (most recent call last):
File "threading.pyo", line 486, in __bootstrap_inner
Unhandled exception in thread started by
Error in sys.excepthook:

Original exception was:

由于急用,所以当时没有和py2exe纠缠,用cx_Freeze打包发布了,并且运行正常。晚上研究了一下这个问题,总算找到了原因。

原来在解释器下,主程序会在各个线程执行完退出。而py2exe打包后,主程序在启动线程后(不等线程执行完)就退出了,代码里又没有指定主程序必须在线程执行完后退出,所以会出现错误。

举个例子:


import threading
import time
import sys

class th(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
print self.getName(),'start'
time.sleep(5)
print self.getName(),'end'

my_thread=th()
my_thread.start()
my_thread=th()
my_thread.start()
my_thread=th()
my_thread.start()
my_thread=th()
my_thread.start()

在python环境下运行的很好,最后输出

Thread-1 start
Thread-2 start
Thread-3 start
Thread-4 start
Thread-2 end
Thread-4 end
Thread-1 end
Thread-3 end

py2exe编译一下执行,输出

Thread-1 start
Thread-2 start
Thread-3 start
Unhandled exception in thread started by
Error in sys.excepthook:

Original exception was:

把程序改一改,加入线程执行完才退出的脚本,变为

import threading
import time
import sys

class th(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
print self.getName(),'start'
time.sleep(5)
print self.getName(),'end'

my_thread=th()
my_thread.start()
my_thread=th()
my_thread.start()
my_thread=th()
my_thread.start()
my_thread=th()
my_thread.start()

while True:
if len(threading.enumerate())==1:
sys.exit()

这样就行了,py2exe编译后也能执行了!当然用线程队列来实现也是可以的,而且似乎比这样更好,呵呵。
添加评论:
  • 你的名字:
  • E-mail:
  • 验证码:
  • 内容:
  • (必填)
  • (必填,不显示)
  • ddd(必填)
  • (必填)
  • 请记住我