【发布时间】:2014-07-07 18:18:17
【问题描述】:
下面的代码按我预期的方式工作,即:
- 有一个 QThread(“Ernie”)从 1 计数到 8,计数之间休眠 1 秒
- 有一个免费的 UI 小部件(“Bert”)
- 在正常操作下,程序会一直运行,直到线程结束并关闭 UI
- Ctrl-C 键盘中断将在正常完成之前正常停止程序。
为此,我必须将 1 秒的睡眠分成 50 毫秒的块来检查标志。
是否有更 Pythonic 的方式在线程中休眠一段时间(例如 1 秒)但可以被某些标志或信号中断?
try:
for i in xrange(8):
print "i=%d" % i
for _ in xrange(20):
time.sleep(0.05)
if not self.running:
raise GracefulShutdown
except GracefulShutdown:
print "ernie exiting"
我宁愿这样做,并以某种方式在线程中导致 GracefulShutdown 异常:
try:
for i in xrange(8):
print "i=%d" % i
time.sleep(1)
# somehow allow another thread to raise GracefulShutdown
# during the sleep() call
except GracefulShutdown:
print "ernie exiting"
完整程序;
from PySide import QtCore, QtGui
from PySide.QtGui import QApplication
import sys
import signal
import time
class GracefulShutdown(Exception):
pass
class Ernie(QtCore.QThread):
def __init__(self):
super(Ernie, self).__init__()
self.running = True
def run(self):
try:
for i in xrange(8):
print "i=%d" % i
for _ in xrange(20):
time.sleep(0.05)
if not self.running:
raise GracefulShutdown
except GracefulShutdown:
print "ernie exiting"
def shutdown(self):
print "ernie received request to shutdown"
self.running = False
class Bert(object):
def __init__(self, argv):
self.app = QApplication(argv)
self.app.quitOnLastWindowClosed = False
def show(self):
widg = QtGui.QWidget()
widg.resize(250, 150)
widg.setWindowTitle('Simple')
widg.show()
self.widg = widg
return widg
def shutdown(self):
print "bert exiting"
self.widg.close()
def start(self):
# return control to the Python interpreter briefly every 100 msec
timer = QtCore.QTimer()
timer.start(100)
timer.timeout.connect(lambda: None)
return self.app.exec_()
def handleInterrupts(*actors):
def handler(sig, frame):
print "caught interrupt"
for actor in actors:
actor.shutdown()
signal.signal(signal.SIGINT, handler)
bert = Bert(sys.argv)
gratuitousWidget = bert.show()
ernie = Ernie()
ernie.start()
handleInterrupts(bert, ernie)
retval = bert.start()
print "bert finished"
while not ernie.wait(100):
# return control to the Python interpreter briefly every 100 msec
pass
print "ernie finished"
sys.exit(retval)
【问题讨论】:
标签: python multithreading