QThread блокирует декодирование UTF-16, когда код python замораживается cx_Freeze?

На самом деле проблема представляет собой серьезную ошибку в огромной системе, и мы упростим проблему до фрагмента кода ниже. Мы хотим выяснить, почему поведение потоков отличается в коде Python и в exe-файле.

Код включает в себя два потока, и мы ожидаем, что оба потока могут работать одновременно и завершаться в Windows 7 (64-разрядная версия) с Python 2.7.

Код работает правильно, когда я использую CPython напрямую, скажем, используя "python tThread.py" в консоли. Оба потока работают и заканчиваются нормально.

Однако, когда код замораживается в exe с помощью cx_Freeze 5.0.1 и выполняется, подпоток блокируется в строке 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()

Ниже приведен файл setup.py для cx_Freeze:

(консольная команда "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. Пожалуйста, помогите нам найти решение, позволяющее потоку передать код декодирования, спасибо.


После сложной отладки в течение нескольких дней мы находим блоки потоков в этой строке в $Python27$\Lib\encodings\__init__.py.

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

cx_Freeze имеет ошибку для импорта модуля во время выполнения в многопоточном режиме.


Наконец, мы обходим блокирующий код с помощью хак-кода, скажем, вручную импортируем модули вне кода потока. Однако мы не думаем, что это элегантное решение, поскольку все еще существует скрытая ошибка импорта, которая может произойти в будущем. Надеемся, что автор cx_Freeze сможет исправить ошибку и предоставить идеальное решение нашего вопроса.


person Azure    schedule 16.05.2017    source источник


Ответы (1)


Автор cx_Freeze исправил ошибку и обновил ее до версии 5.0.2.

Соответствующая проблема находится здесь

person Azure    schedule 30.05.2017