当 python 代码被 cx_Freeze 冻结时,解码 UTF-16 中的 QThread 块?



事实上,这个问题是一个庞大系统中的一个严重错误,我们将问题简化为下面的代码片段。我们想弄清楚为什么 python 代码和 exe 文件中的线程行为不同。

代码包括两个线程,我们希望这两个线程可以同时运行,并在带有python 2.7的Windows 7(64位)中终止。

当我直接使用CPython时,代码可以正常运行,例如,在控制台中使用"python tThread.py"。两个线程都正常运行和完成。

但是,当代码使用cx_Freeze 5.0.1冻结为 exe 并执行时,子线程块在行uu = u16.decode("utf-16"),而主线程进入死循环。

以下是tThread.py

# -*- coding: UTF-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')  
import time
from PySide import QtGui, QtCore
from PySide.QtCore import *
from PySide.QtGui import *
class Worker(QObject):
done = QtCore.Signal()
def longRun(self):
count = 1
while count < 20:
print "Worker Thread", count
u16 = u"ABCD".encode("utf-16")
uu = u16.decode("utf-16")     # Block here <---
count += 1
self.done.emit()

def mainThread():
app = QApplication([])
objThread = QThread()
obj = Worker()
obj.moveToThread(objThread)
obj.done.connect(objThread.quit)
objThread.started.connect(obj.longRun)
objThread.start()

i = 1
while not objThread.isFinished():
QCoreApplication.processEvents()
print "Main Thread", i
time.sleep(0.1)
i+=1
print "Main Thread Over"
mainThread()
sys.exit()

以下是cx_Freeze的setup.py文件:

(控制台命令是">python setup.py build_exe -b build")

from cx_Freeze import setup, Executable
import platform
build_exe_options = {
"packages": [ "PySide"],
"include_msvcr": True
};
exe = Executable(u".\tThread.py", base=None, targetName="tThread.exe" )
setup(  name = "tThread",
version = "0.1",
description = u"tThread",
options = {"build_exe": build_exe_options},
executables = [exe])

我们怀疑cx_Freeze中存在错误,这导致了原始代码和exe之间的不同行为。 请帮助我们找到解决方案,使线程通过解码代码,谢谢。


经过几天的艰难调试,我们在$Python 27$\Lib\encodings\__init__.py中找到了这一行中的线程块

mod = __import__('encodings.' + modname, fromlist=_import_tail,level=0)

cx_Freeze在多线程中存在运行时模块导入的错误。


最后,我们使用hack代码绕过阻塞代码,例如,手动导入线程代码之外的模块。但是,我们认为这不是一个优雅的解决方案,因为将来仍然可能存在隐藏的导入错误。 希望cx_Freeze的作者能够修复该错误并为我们的问题提供完美的解决方案。

cx_Freeze的作者已经解决了这个错误并将其更新到 5.0.2 .

相关问题在这里

最新更新