一个锁,保证同时间只有一个python3在运行当前脚本
主要用途是使用cron定时运行脚本的时候,避免重复运行
import os
import sys
import asyncio
import signal
import logging
import traceback
logging.basicConfig(filename='./script.log', level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
LOCK_FILE = "/tmp/script.lock"
async def main():
try:
# 在这里编写你的主任务逻辑
pass
except asyncio.CancelledError:
log_message = "主任务被取消"
logging.info(log_message)
except Exception as e:
log_message = f"错误信息 = {e}, trace = {traceback.format_exc()}"
logging.error(log_message)
async def stop_program():
asyncio.get_running_loop().stop()
def handle_sigterm():
log_message = "收到 SIGTERM 信号,正在退出..."
logging.info(log_message)
asyncio.create_task(stop_program())
async def start():
# 检查是否存在锁文件
if os.path.exists(LOCK_FILE):
with open(LOCK_FILE, 'r') as f:
pid = f.read().strip()
# 如果锁文件存在,并且其中记录的进程 ID 不是当前进程 ID,则说明已经有另一个进程在运行该脚本,因此退出
if pid.isdigit() and int(pid) != os.getpid():
log_message = f"Another pid({pid}) is already running this script. Exiting."
logging.error(log_message)
sys.exit(0) # 正常退出
else: # 锁文件不存在或者pid就是当前pid
with open(LOCK_FILE, 'w') as f:
f.write(str(os.getpid()))
else:
# 如果锁文件不存在,则创建并写入当前进程 ID
with open(LOCK_FILE, 'w') as f:
f.write(str(os.getpid()))
try:
# 创建并执行主任务
run_main_task = asyncio.create_task(main())
await run_main_task
except KeyboardInterrupt:
logging.error("收到键盘中断信号,正在退出...")
if not run_main_task.done():
run_main_task.cancel() # 取消主任务
await run_main_task # 等待主任务完成
finally:
# 无论脚本是否成功执行,都删除锁文件
os.remove(LOCK_FILE)
# 设置 SIGTERM 信号处理函数
signal.signal(signal.SIGTERM, handle_sigterm)
# 启动事件循环
asyncio.run(start())