停止 systemd 服务 运行 一个 python 程序

Stop systemd service running a python program

我为 运行 一个 Python 程序创建了一个服务,并添加了一些代码行来创建一个锁以避免启动它两次。

不幸的是,我不知道如何配置服务以正确停止 运行ning 程序。当 运行 停止命令时它不会删除锁,然后我无法再启动该服务。如果我自己通过 CLI 执行程序并使用 Ctrl+C 退出,锁将被删除。

我已阅读有关 KillMode, ExecStop and Signal 的手册。我的理解是默认配置是我需要的。

有什么帮助吗?

主程序

if __name__ == '__main__':

    #Creating lock to avoid launching program twice
    lock = pathlib.Path("program.lock")

    if not lock.exists():

        lock_acquired_on = datetime.now()

        with open('program.lock', 'w') as lock:
            lock.write(f'Lock acquired on {lock_acquired_on}')
            logger.info('Added lock file to avoid running the program twice.')
    
        try:
            while True:

                #Doing stuff here


        except KeyboardInterrupt:
            close_program() #Close other threads

        #Removing the lock file
        os.remove(pathlib.Path("program.lock"))

    else:
        with open('program.lock', 'r') as lock:
            lock_acquisition_time = str(lock.readlines()[0])
            logger.info('Programme Maquette Status is already running.') 
            logger.info(lock_acquisition_time)

服务

[Unit]
Description=Programme Maquette IoT End-to-End
After=multi-user.target
Conflicts=getty@tty1.service

[Service]
WorkingDirectory=/home/pi/Documents/ProductionMaquette
Type=simple
ExecStart=/usr/local/bin/python3.8 /home/pi/Documents/ProductionMaquette/Lo_main.py
StandardInput=tty-force

[Install]
WantedBy=multi-user.target

Systemd 将 SIGTERM 发送到进程 - 因此您需要处理它。

因此下面的小示例使用 SIGTERM 的信号处理程序来清理文件。实际上它使用 atexit 来清理文件,因为它也处理标准的退出条件和一个信号处理程序以在接收到 SIGTERM 信号[=时以“正常”clos启动进程14=]

import atexit
import signal
import os

locking_file = "/var/lock/my_service.lock"

if __name__ == '__main__':

    def clean_lock():
        # atexit handler to clean up a file
        os.remove(locking_file)

    def signal_term_handler(sigNum, frame):
        # on receiving a signal initiate a normal exit
        raise SystemExit('terminating')

    with open("test_file.lock", "w") as lock:
         while True:
             lock.write("x")
             time.sleep(10)

    # register the cleanup handler
    atexit.register(clean_lock)
    # register the signal handler
    signal.signal(signal.SIGTERM, signal_term_handler)

注意:您可能需要查看一个文件锁定库:https://pypi.org/project/filelock/ 因为它也应该处理该用例。

它不仅测试文件的存在,而且使用os-文件锁定机制。 IE。不仅要测试文件是否存在,还要测试它是否可以锁定。实际上,这意味着即使文件仍然存在但之前的进程已终止,这也不是问题,因为文件不再被锁定。