繁体   English   中英

停止运行 python 程序的 systemd 服务

[英]Stop systemd service running a python program

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

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

我已经阅读了有关KillModeExecStopSignal的手册。 我的理解是默认配置是我需要的。

有什么帮助吗?

主程序

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信号时启动进程的“正常”关闭

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/因为它也应该处理该用例。

它不仅测试文件的存在,而且使用操作系统文件锁定机制。 即不仅测试了文件的存在性——而且还测试了它是否可以被锁定。 实际上,这意味着即使文件仍然存在但先前的进程已死亡,这也不是问题,因为文件不再被锁定。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM