脚本如何暂停恢复任务

wen 实用脚本 24

本文目录导读:

脚本如何暂停恢复任务

  1. 操作系统级别(进程暂停/恢复)
  2. Python 脚本内部暂停/恢复
  3. Bash 脚本暂停/恢复
  4. 定时任务(Cron)暂停/恢复
  5. 分布式任务队列(如 Celery)
  6. 综合示例:带状态监控的脚本
  7. 最佳实践建议

脚本的暂停与恢复有多种实现方式,具体取决于你的使用场景(是系统进程管理、定时任务,还是代码内部的流程控制),下面按常见场景分类说明:

操作系统级别(进程暂停/恢复)

Linux / Unix 使用信号

# 暂停进程(发送 SIGSTOP 信号)
kill -STOP <PID>
# 恢复进程(发送 SIGCONT 信号)
kill -CONT <PID>
# 示例:暂停当前脚本自身
trap 'echo "Paused"; kill -STOP $$; echo "Resumed"' SIGTSTP

Windows 使用 PowerShell

# 暂停进程
Suspend-Process -Name "notepad"
# 恢复进程
Resume-Process -Name "notepad"

Python 脚本内部暂停/恢复

使用 threading.Event(推荐)

import threading
import time
class PauseableTask:
    def __init__(self):
        self.pause_event = threading.Event()
        self.pause_event.set()  # 初始为运行状态
    def pause(self):
        self.pause_event.clear()
    def resume(self):
        self.pause_event.set()
    def run(self):
        while True:
            self.pause_event.wait()  # 暂停时会阻塞在这里
            # 执行实际任务
            print("Working...")
            time.sleep(1)

使用信号处理

import signal
import time
paused = False
def handler(signum, frame):
    global paused
    paused = not paused
    if paused:
        print("Paused")
    else:
        print("Resumed")
signal.signal(signal.SIGTSTP, handler)
while True:
    while paused:
        time.sleep(0.1)
    # 实际任务代码
    print("Running...")
    time.sleep(1)

Bash 脚本暂停/恢复

简单方式

#!/bin/bash
trap 'echo "Paused"; kill -STOP $$; echo "Resumed"' SIGTSTP
while true; do
    echo "Running task..."
    sleep 1
done

使用文件锁控制

#!/bin/bash
PAUSE_FILE="/tmp/script_pause"
while true; do
    # 检查暂停文件是否存在
    if [ -f "$PAUSE_FILE" ]; then
        echo "Paused, waiting..."
        sleep 1
        continue
    fi
    # 实际任务
    echo "Working..."
    sleep 1
done

定时任务(Cron)暂停/恢复

禁用/启用 Cron 任务

# 暂停(注释掉任务)
crontab -e
# 在任务前加 # 注释
# 恢复(去掉注释)
crontab -e
# 删除 #

使用控制脚本

#!/bin/bash
# control.sh
case "$1" in
    pause)
        touch /tmp/cron_paused
        ;;
    resume)
        rm -f /tmp/cron_paused
        ;;
    status)
        if [ -f /tmp/cron_paused ]; then
            echo "Paused"
        else
            echo "Running"
        fi
        ;;
esac

分布式任务队列(如 Celery)

# 暂停特定任务队列
celery control cancel_consumer -d my_queue
# 恢复
celery control add_consumer my_queue
# 或通过代码
from celery import current_app
current_app.control.cancel_consumer('my_queue')
current_app.control.add_consumer('my_queue')

综合示例:带状态监控的脚本

#!/usr/bin/env python3
import json
import time
import os
class TaskManager:
    def __init__(self, status_file="task_status.json"):
        self.status_file = status_file
        self.init_status()
    def init_status(self):
        if not os.path.exists(self.status_file):
            self.set_status("running")
    def set_status(self, status):
        with open(self.status_file, 'w') as f:
            json.dump({"status": status, "timestamp": time.time()}, f)
    def get_status(self):
        try:
            with open(self.status_file, 'r') as f:
                return json.load(f)["status"]
        except:
            return "unknown"
    def pause(self):
        self.set_status("paused")
        print("Task paused")
    def resume(self):
        self.set_status("running")
        print("Task resumed")
    def run(self):
        while True:
            status = self.get_status()
            if status == "paused":
                time.sleep(1)
                continue
            elif status == "stopped":
                print("Task stopped")
                break
            # 执行任务
            print(f"Running task at {time.time()}")
            time.sleep(2)
if __name__ == "__main__":
    tm = TaskManager()
    # 可以通过外部命令控制
    # python script.py pause
    # python script.py resume
    import sys
    if len(sys.argv) > 1:
        cmd = sys.argv[1]
        if cmd == "pause":
            tm.pause()
        elif cmd == "resume":
            tm.resume()
        elif cmd == "stop":
            tm.set_status("stopped")
    else:
        tm.run()

最佳实践建议

  1. 选择适当的方法

    • 系统进程:使用信号
    • 单脚本:使用 Event 或全局变量
    • 分布式系统:使用任务队列的控制接口
  2. 状态持久化:如果需要重启后保持状态,使用文件或数据库

  3. 优雅处理:暂停时确保当前任务完成,避免数据不一致

  4. 监控与日志:记录暂停/恢复的时间点和原因

根据你的具体场景(是控制单个脚本、整个系统进程,还是分布式任务),选择最合适的实现方式。

抱歉,评论功能暂时关闭!