gpt4 book ai didi

python - 从 python 守护进程启动线程的正确方法

转载 作者:太空宇宙 更新时间:2023-11-03 18:19:20 33 4
gpt4 key购买 nike

我需要编写带有 Web 界面的简单守护程序。

这个想法是使用python-daemon package并在一个线程内运行 wsgiref.simple_server

守护进程可以与以下代码一起正常工作:

import daemon
import logging
import time
import signal
import threading

logfilename = '/var/log/testdaemon.log'
logger = logging.getLogger("DaemonLog")
logger.setLevel(logging.INFO)
formatter = logging.Formatter(
'%(asctime)s:%(levelname)s:%(message)s',
'%Y-%m-%d %H:%M:%S')
handler = logging.FileHandler(logfilename)
handler.setFormatter(formatter)
logger.addHandler(handler)

def initial_program_setup():
logger.info('daemon started')

def do_main_program():
while True:
time.sleep(1)
logger.info('another second passed')

def program_cleanup(signum, frame):
logger.info('daemon stops')
context.terminate(signum, frame)

def reload_program_config(signum, frame):
logger.info('reloading config')

context = daemon.DaemonContext()

context.signal_map = {
signal.SIGTERM: program_cleanup,
signal.SIGHUP: 'terminate',
signal.SIGUSR1: reload_program_config,
}

context.files_preserve = [handler.stream]

initial_program_setup()

with context:
do_main_program()

但是如果我在 initial_program_setup() 中启动一个线程,如下所示:

def web_gui():
logger.info('weg gui started')

web = threading.Thread(target=web_gui)
web.setDaemon(True)

def initial_program_setup():
logger.info('daemon started')
web.start()

看起来守护进程在线程完成后退出。添加类似的内容

while True:
time.sleep(1)

to web_gui() (让线程永远运行,就像 Web 服务器应该的那样)使情况变得更糟:甚至连 web gui started 行也没有显示在日志中。

我的问题是:

  1. 为什么这不起作用?在守护进程中启动线程的正确方法是什么?
  2. 也许有更好的方法通过 Web 界面控制守护进程?在这样的架构下,我认为我应该为每个界面页面启动一个新的线程,这很难扩展。

谢谢。

最佳答案

这是守护程序库的限制 ( discussion thread starts here )。

TL;DR:您的选择是:

  • 不要使用守护进程,因为它在这方面已无法修复。
  • 在“with daemoncontext” block 中启动线程。

长版:

当守护程序库切换到守护程序上下文时,它会执行双 fork 。这意味着它首先 fork 然后杀死父进程。新的 fork 没有任何线程,因此退出父进程相当于杀死你的 webgui 线程。最终,此问题的任何解决方案都必须在新创建的子进程中启动任何永久线程。在守护进程上下文中执行此操作的缺点是您无法再将潜在错误传播给用户。理想情况下,您可以双 fork ,但不退出父进程,然后设置守护进程,并在进入主循环之前使父进程退出。这是守护程序库或任何实现 PEP3143 草案的库无法实现的。

关于python - 从 python 守护进程启动线程的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24424257/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com