【问题标题】:QThread blocks in decoding UTF-16 when python code is freezed by cx_Freeze?当python代码被cx_Freeze冻结时,QThread在解码UTF-16时会阻塞?
【发布时间】:2017-05-16 13:37:10
【问题描述】:

其实这个问题是一个庞大系统的严重bug,我们把这个问题简化成下面的sn-p代码。我们想弄清楚为什么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 中存在错误,导致 raw code 和 exe 之间的行为不同。 请帮助我们找到使线程通过解码代码的解决方案,谢谢。


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

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

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


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

【问题讨论】:

    标签: python multithreading qt pyside cx-freeze


    【解决方案1】:

    cx_Freeze的作者已经解决了这个bug并更新到了5.0.2。

    相关问题是Here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-04
      • 2021-07-29
      • 2021-09-28
      • 2020-08-02
      • 1970-01-01
      • 2011-08-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多