2017-05-16 8 views
1

실제로이 문제는 거대한 시스템의 심각한 버그이며 아래의 코드 조각으로 문제를 단순화합니다. 우리는 파이썬 코드와 exe 파일에서 스레드 동작이 다른 이유를 알아 내고 싶습니다.QThread는 cx_Freeze에 의해 파이썬 코드가 고정 될 때 UTF-16 디코딩을 차단합니까?

코드에는 두 개의 스레드가 포함되어 있으며 두 스레드가 모두 동시에 실행될 수 있고 Python 2.7로 Windows 7 (64 비트)에서 종료 될 것으로 예상됩니다.

CPython을 직접 (예 : 콘솔에서 "python tThread.py"사용) 사용하면 코드가 올바르게 실행됩니다. 두 스레드 모두 실행되고 정상적으로 완료됩니다. 코드 cx_Freeze 5.0.1와 EXE로 동결되고 실행될 그러나

, 광고 = u16.decode UU ("UTF-16")의 서브 스레드 블록, 메인 쓰레드 죽은 들어가는 반면 고리.

(콘솔 명령이 "파이썬 setup.py build_exe -b를 구축 :

다음
# -*- 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 파일입니다

다음은 tThread.py입니다 ")

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 사이의 다른 동작을 유발합니다. 스레드가 디코드 코드를 전달하도록 솔루션을 찾도록 도와주세요, 감사합니다.


며칠 어려운 디버깅 후, 우리는

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

나 cx_Freeze init__.py __ \ $ Python27 $ \ lib 디렉토리 \ 인코딩이 줄 스레드 블록을 찾으 런타임 모듈에 대한 버그가 - 멀티 스레딩에서 가져옵니다.


마지막으로 우리는 해킹 코드를 사용하여 차단 코드를 우회합니다. 예를 들어 스레드 코드 외부에서 수동으로 모듈을 가져옵니다. 그러나 미래에 발생할 수있는 숨겨진 가져 오기 버그가 여전히 있으므로 우아한 솔루션이라고 생각하지 않습니다. cx_Freeze의 제작자가 버그를 수정하고 우리의 질문에 대한 완벽한 해결책을 제공하기를 희망합니다.

답변

0

cx_Freeze의 저자는 버그를 해결하고 5.0.2로 업데이트했습니다.

관련 문제는 Here

입니다.