簡體   English   中英

PySide QThread.terminate()導致致命的python錯誤

[英]PySide QThread.terminate() causing fatal python error

我正在使用PySide版本1.2.2,它包裝了Qt v4.8框架。 我處於這樣一種情況,我必須選擇讓我的應用程序等待一個我不再需要正常退出的QThread (線程很可能無限期地阻塞),並給予無響應的線程一個寬限期(幾個秒),然后在其上調用QThread.terminate() 雖然我希望我可以,但是當底層線程仍在運行時,我不能讓QThread對象超出范圍,因為這會拋出錯誤“QThread:在線程仍在運行時被銷毀”並且幾乎​​肯定會導致段錯誤。

請注意,我知道終止QThread是危險的,非常氣餒 我只想在這里探索我的選擇。

但是,當我嘗試終止一個線程時,我的應用程序崩潰並出現以下錯誤:

致命的Python錯誤:此線程狀態在釋放時必須是最新的

您可以通過復制/粘貼並運行以下代碼來自行嘗試:

from PySide import QtCore, QtGui

class Looper(QtCore.QThread):
    """QThread that prints natural numbers, one by one to stdout."""
    def __init__(self, *args, **kwargs):
        super(Looper, self).__init__(*args, **kwargs)
        self.setTerminationEnabled(True)

    def run(self):
        i = 0
        while True:
            self.msleep(100)
            print(i)
            i += 1

# Initialize and start a looper.                                                                      
looper = Looper()
looper.start()

# Sleep main thread for 5 seconds.                                                                    
QtCore.QThread.sleep(5)

# Terminate looper.                                                                                   
looper.terminate()

# After calling terminate(), we should call looper.wait() or listen
# for the QThread.terminated signal, but that is irrelevant for
# the purpose of this example.

app = QtGui.QApplication([])
app.exec_()

你如何在Python中正確終止QThreads?

我認為我得到的錯誤與發布全局解釋器鎖有關,但我不確定到底出了什么問題,以及如何解決它。

看起來這個錯誤可能是PySide特有的:用PyQt4運行你的例子根本不會產生任何錯誤。

至於如何安全地終止QThread的一般問題:它完全取決於你對線程中正在進行的工作的控制程度。 如果它實際上是一個可以定期檢查標志的循環,那么解決方案很簡單:

class Looper(QtCore.QThread):
    ...         

    def interrupt(self):
        self._active = False

    def run(self):
        i = 0
        self._active = True
        while self._active:
            self.msleep(100)
            print(i)
            i += 1

app = QtGui.QApplication([])

looper = Looper()
looper.finished.connect(app.quit)
looper.start()

QtCore.QTimer.singleShot(3000, looper.interrupt)

app.exec_()

一旦run方法返回,線程就會干凈地完成,所以你必須找到一些允許這種情況發生的機制。 如果你不能這樣做(也許是因為在線程中完成的工作很大程度上是你無法控制的),你應該考慮改用多處理方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM