我无法停止我的 Gevent 网络服务器,因为我的 stop()
函数从未被调用过。
我的 Gevent 网络服务器 (serve_forever()
) 在单个 QThread 线程中运行。
我的主要应用程序是 (QCoreApplication) 用 PySide2 编写的。
我尝试了什么
stop()
的插槽从未被激活 -> 我认为 server_forever() 正在阻塞它?!stop()
不得从同一线程内调用 -> 不幸的是,我不知道如何安全地从另一个线程调用方法。我认为这正是信号/插槽的用途更新工作示例:
main.py
import sys
from PySide2.QtCore import QCoreApplication, QTimer
from T_CTRL import T_CTRL
def main():
# create application
app = QCoreApplication.instance()
if app is None:
app = QCoreApplication(sys.argv)
# connect: cleanup application before quitting
app.aboutToQuit.connect(app.deleteLater)
# create my control object
myCtrl = T_CTRL()
# # create helper timer, so that quit signals can be received
timerHelper = QTimer()
timerHelper.start(500)
timerHelper.timeout.connect(lambda: None) # Let the interpreter run each 500 ms.
# run application and create main event handler
return app.exec_()
if __name__ == '__main__':
main()
T_CTRL.py
from PySide2 import QtCore
from PySide2.QtCore import QThread, QCoreApplication
from T_Web_Worker import ThreadWorker
import signal
from functools import partial
class T_CTRL(QtCore.QObject):
# signals
sigShutdown = QtCore.Signal()
def __init__(self):
# init
super(T_CTRL, self).__init__()
# create objects
self.t = QThread()
self.worker = ThreadWorker()
# connect quit signals to sigint_handler
signal.signal(signal.SIGINT, partial(self.sigint_handler, str1=""))
signal.signal(signal.SIGTERM, partial(self.sigint_handler, str1=""))
# move worker to thread
self.worker.moveToThread(self.t)
# connect: startServer() when thread has started
self.t.started.connect(self.worker.startServer)
# connect: requestServerStop() when Sigint handler has been activated
self.sigShutdown.connect(self.worker.requestServerStop)
# connect: webserver told that is has shut down, now stop the thread
self.worker.sigServerShutdownFinished.connect(self.t.quit)
self.worker.sigServerShutdownFinished.connect(self.worker.deleteLater)
# connect: thread has finished, now quit the application
self.t.finished.connect(self.t.deleteLater)
self.t.finished.connect(self.quit_now)
# start the thread
self.t.start()
def sigint_handler(self, signal, frame, str1):
print ("T_CTRL: Slot 'sigint_handler' activated. Emitting signal 'sigShutdown'")
self.sigShutdown.emit()
QCoreApplication.processEvents()
@QtCore.Slot()
def quit_now(self):
print ("_CTRL: slot 'quit_now' activated, quitting application")
QCoreApplication.quit()
T_Web_Worker
from PySide2 import QtCore
from PySide2.QtCore import QCoreApplication
from flask import Flask
from gevent.pywsgi import WSGIServer
class ThreadWorker(QtCore.QObject):
# init flask & tornado
app = Flask(__name__)
http_server = None
# signal to feedback, that worker has finished
sigServerShutdownFinished = QtCore.Signal()
def __init__(self):
super(ThreadWorker, self).__init__()
# start requested by main thread
@QtCore.Slot()
def startServer(self):
print ("T_Web_Worker: Slot 'startServer' activated")
self.http_server = WSGIServer(('127.0.0.1', 5000), self.app)
self.http_server.serve_forever()
QCoreApplication.processEvents()
# shutdown requested by main thread
@QtCore.Slot()
def requestServerStop(self):
print("T_Web_Worker: Slot 'requestServerStop' activated. Emitting signal 'sigServerShutdownFinished'")
self.http_server.stop(timeout=5)
self.sigServerShutdownFinished.emit()
QCoreApplication.processEvents()