在程序中使用线程时,Systemd在停止时未接收到SIGTERM

2024-04-28 11:32:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我想创建一个作为systemd服务运行的python程序。我希望能优雅地阻止它。我遇到了一个奇怪的行为:当我使用线程时,python程序在systemctl stop example.service上没有接收到SIGTERM信号,但是如果我不使用线程,一切都会正常工作。示例如下:

没有螺纹。(服务接收到SIGTERM信号并按预期停止):

import signal
import time
import threading
import sys

RUN=True

# catch SIGINT and SIGTERM and stop application
def signal_handler(sig, frame):
    global RUN
    print("Got signal: "+str(sig))
    RUN=False
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)

# some working thread inside application
def my_thread():
    global RUN
    while RUN:
        print("sleep")
        time.sleep(1.0)

my_thread()
print("Done.")

stopping a program without threads works

有螺纹。(程序不接收SIGTERM信号,超时后被SIGKILL强制终止):

^{pr2}$

stopping a program with threads does not work

Systemd服务文件:

[Unit]
Description=Example service

[Install]
WantedBy=multi-user.target

[Service]
ExecStart=/usr/bin/python /opt/program/main.py
TimeoutSec=60
Restart=on-failure
Type=simple
User=mixo
Group=mixo

我的程序需要多个线程,所以我希望能够优雅地停止服务,即使我在我的程序中使用线程。我做错什么了?在


Tags: runimport程序signaltime信号service线程
1条回答
网友
1楼 · 发布于 2024-04-28 11:32:28

感谢@Shawn提出了这个旧的post,我现在解决了这个问题。在

问题在于如何在python中实现信号处理程序。行t.join()阻塞了我的主线程,因此无法接收任何信号。有两种简单的解决方案:

1)使用python 3.x

或2)使用信号暂停()等待这样的信号:

import signal
import time
import threading
import sys

RUN=True

# catch SIGINT and SIGTERM and stop application
def signal_handler(sig, frame):
    global RUN
    print("Got signal: "+str(sig))
    RUN=False
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)

# some working thread inside application
def my_thread():
    global RUN
    while RUN:
        print("sleep")
        time.sleep(1.0)

# wait for thread to complete and exit
t = threading.Thread(target=my_thread)
t.start()
signal.pause()
t.join()
print("Done.")

相关问题 更多 >