[英]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.