代码之家  ›  专栏  ›  技术社区  ›  miXo

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

  •  0
  • miXo  · 技术社区  · 6 年前

    我想创建一个python程序,它作为systemd服务运行。我想能优雅地阻止它。我遇到了一个奇怪的行为:当我使用线程时,python程序在 systemctl stop example.service ,但如果我不使用线程,一切都可以正常工作。示例如下:

    没有线。(服务接收到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强制终止):

    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()
    t.join()
    print("Done.")
    

    stopping a program with threads does not work

    系统服务文件:

    [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
    

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

    1 回复  |  直到 6 年前
        1
  •  0
  •   miXo    6 年前

    多亏了@Shawn post ,我现在已经解决了这个问题。

    问题在于如何在python中实现信号处理程序。线路 t.join()

    1) 使用python 3.x

    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.")