簡體   English   中英

CherryPy干擾Windows上的Twisted關閉

[英]CherryPy interferes with Twisted shutting down on Windows

我有一個運行Twisted的應用程序,在啟動一些其他線程(包括CherryPy Web服務器reactor.run()在我的主線程中使用reactor.run()啟動reactor。 這是一個在Linux上按下Ctrl + C但在Windows上沒有按下時干凈關閉的程序:

from threading import Thread
from signal import signal, SIGINT

import cherrypy

from twisted.internet import reactor
from twisted.web.client import getPage

def stop(signum, frame):
    cherrypy.engine.exit()
    reactor.callFromThread(reactor.stop)
signal(SIGINT, stop)

class Root:
    @cherrypy.expose
    def index(self):
        reactor.callFromThread(kickoff)
        return "Hello World!"

cherrypy.server.socket_host = "0.0.0.0"
Thread(target=cherrypy.quickstart, args=[Root()]).start()

def print_page(html):
    print(html)

def kickoff():
    getPage("http://acpstats/account/login").addCallback(print_page)

reactor.run()

我相信CherryPy是罪魁禍首,因為這是我在沒有CherryPy的情況下編寫的另一個程序,當按下Ctrl + C時,它在Linux和Windows上都會干凈地關閉:

from time import sleep
from threading import Thread
from signal import signal, SIGINT

from twisted.internet import reactor
from twisted.web.client import getPage

keep_going = True
def stop(signum, frame):
    global keep_going
    keep_going = False
    reactor.callFromThread(reactor.stop)
signal(SIGINT, stop)

def print_page(html):
    print(html)

def kickoff():
    getPage("http://acpstats/account/login").addCallback(print_page)

def periodic_downloader():
    while keep_going:
        reactor.callFromThread(kickoff)
        sleep(5)

Thread(target=periodic_downloader).start()
reactor.run()

有誰知道問題是什么? 這是我的難題:

  • 在Linux上一切正常
  • 在Windows上,當CherryPy未運行時,我可以使用reactor.callFromThread從信號處理程序調用函數
  • 當CherryPy運行時,我從信號處理程序使用reactor.callFromThread調用的函數都不會執行(我已經驗證了信號處理程序本身是否會被調用)

我該怎么辦? 如何在運行CherryPy時從信號處理程序關閉Windows上的Twisted? 這是一個錯誤,還是我錯過了這兩個項目中任何一個的文檔的一些重要部分?

當您調用quickstart時,CherryPy會默認處理信號。 在您的情況下,您可能只需要展開quickstart,這只是幾行,然后挑選。 這里基本上是快速啟動在trunk中的作用:

if config:
    cherrypy.config.update(config)

tree.mount(root, script_name, config)

if hasattr(engine, "signal_handler"):
    engine.signal_handler.subscribe()
if hasattr(engine, "console_control_handler"):
    engine.console_control_handler.subscribe()

engine.start()
engine.block()

在您的情況下,您不需要信號處理程序,因此您可以省略它們。 如果你沒有從主線程啟動CherryPy,你也不需要調用engine.block。 Engine.block()只是讓主線程不立即終止的一種方法,而是等待進程終止(這樣可以自動運行可靠;一些平台在從主線程的任何線程調用execv時都有問題)。

如果你刪除了block()調用,你甚至不需要在quickstart周圍使用Thread()。 所以,替換你的行:

Thread(target=cherrypy.quickstart, args=[Root()]).start()

有:

cherrypy.tree.mount(Root())
cherrypy.engine.start()

暫無
暫無

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

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