سؤال

لدي تطبيق يقوم بتشغيل Twisted عن طريق تشغيل المفاعل reactor.run() في موضوعي الرئيسي بعد بدء بعض المواضيع الأخرى، بما في ذلك خادم الويب CherryPy.إليك برنامج يتم إيقاف تشغيله بشكل نظيف عند الضغط على Ctrl+C على نظام التشغيل Linux وليس على نظام التشغيل 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 والذي يقوم بإيقاف التشغيل بشكل نظيف على كل من Linux وWindows عند الضغط على Ctrl+C:

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()

هل لدى أي شخص أي فكرة ما هي المشكلة؟وهنا لغز بلدي:

  • على لينكس كل شيء يعمل
  • في نظام التشغيل Windows، يمكنني استدعاء وظائف من معالجات الإشارة باستخدام reactor.callFromThread عندما لا يكون CherryPy قيد التشغيل
  • عند تشغيل CherryPy، لا توجد وظيفة أستخدمها reactor.callFromThread سيتم تنفيذ من معالج الإشارة (لقد تحققت من أنه يتم استدعاء معالج الإشارة نفسه)

مالذي استطيع فعله حيال هذا؟كيف يمكنني إيقاف تشغيل Twisted على Windows من معالج الإشارة أثناء تشغيل CherryPy؟هل هذا خطأ، أم أنني ببساطة فاتني جزء مهم من الوثائق الخاصة بأي من هذين المشروعين؟

هل كانت مفيدة؟

المحلول

يتعامل CherryPy مع الإشارات بشكل افتراضي عند الاتصال بـ Quickstart.في حالتك، ربما ينبغي عليك فقط فتح Quickstart، الذي يتكون من بضعة أسطر فقط، ثم الاختيار والاختيار.إليك ما يفعله Quickstart في صندوق السيارة:

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()

في حالتك، لا تحتاج إلى معالجات الإشارة، لذا يمكنك حذفها.لا تحتاج أيضًا إلى الاتصال بـ Engine.block إذا لم تقم بتشغيل CherryPy من الموضوع الرئيسي.Engine.block() هي مجرد طريقة لجعل سلسلة المحادثات الرئيسية لا تنتهي على الفور، ولكن بدلًا من ذلك تنتظر حتى تنتهي العملية (وهذا يعني أن التحميل التلقائي يعمل بشكل موثوق؛تواجه بعض الأنظمة الأساسية مشكلات في الاتصال بـ execv من أي سلسلة رسائل باستثناء السلسلة الرئيسية).

إذا قمت بإزالة استدعاء block()، فلن تحتاج حتى إلى Thread() حول التشغيل السريع.لذا استبدل خطك:

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

مع:

cherrypy.tree.mount(Root())
cherrypy.engine.start()
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top