方法1:使用锁文件(推荐)
#!/bin/bash
# mutex_run.sh - 使用锁文件实现互斥
LOCKFILE="/tmp/myapp.lock"
# 检查锁文件是否存在
if [ -f "$LOCKFILE" ]; then
# 检查进程是否还在运行
if kill -0 $(cat "$LOCKFILE") 2>/dev/null; then
echo "程序已在运行 (PID: $(cat $LOCKFILE))"
exit 1
else
echo "检测到旧的锁文件,删除中..."
rm -f "$LOCKFILE"
fi
fi
# 创建锁文件并写入当前PID
echo $$ > "$LOCKFILE"
# 确保程序退出时删除锁文件
cleanup() {
rm -f "$LOCKFILE"
exit
}
trap cleanup EXIT
# 在这里放置你的程序代码
echo "程序开始运行 (PID: $$)"
sleep 30 # 模拟程序运行
echo "程序运行结束"
方法2:使用flock(Linux专用)
#!/bin/bash
# flock_mutex.sh - 使用flock实现互斥
LOCKFILE="/tmp/myapp_flock.lock"
# 尝试获取锁
exec 200>"$LOCKFILE"
if ! flock -n 200; then
echo "程序已被其他实例运行"
exit 1
fi
# 程序主体
echo "程序开始运行 (PID: $$)"
sleep 30
echo "程序运行结束"
# 释放锁
flock -u 200
方法3:使用mkdir原子操作
#!/bin/bash
# mkdir_mutex.sh - 使用mkdir的原子性
LOCKDIR="/tmp/myapp_mutex"
# 尝试创建目录(原子操作)
if ! mkdir "$LOCKDIR" 2>/dev/null; then
echo "程序正在运行中"
exit 1
fi
# 确保退出时删除目录
trap 'rm -rf "$LOCKDIR"' EXIT
# 程序主体
echo "程序开始运行 (PID: $$)"
sleep 30
echo "程序运行结束"
方法4:使用系统信号量(Linux)
#!/bin/bash
# sem_mutex.sh - 使用信号量实现互斥
SEM_NAME="myapp_sem"
# 创建信号量
if ! semaphore_ac "$SEM_NAME" 2>/dev/null; then
# 如果没有semaphore工具,使用备用方案
echo "程序已在运行"
exit 1
fi
# 程序主体
echo "程序开始运行"
sleep 30
echo "程序运行结束"
# 释放信号量
semaphore_re "$SEM_NAME"
方法5:使用Python实现(跨平台)
#!/usr/bin/env python3
# mutex.py - Python实现互斥运行
import os
import sys
import fcntl
import time
class Mutex:
def __init__(self, lock_file="/tmp/python_app.lock"):
self.lock_file = lock_file
self.fd = None
def acquire(self):
try:
self.fd = open(self.lock_file, 'w')
fcntl.flock(self.fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
return True
except (IOError, OSError):
return False
def release(self):
if self.fd:
fcntl.flock(self.fd, fcntl.LOCK_UN)
self.fd.close()
os.remove(self.lock_file)
def main():
mutex = Mutex()
if not mutex.acquire():
print("程序已在运行")
sys.exit(1)
try:
print(f"程序开始运行 (PID: {os.getpid()})")
time.sleep(30) # 模拟程序运行
print("程序运行结束")
finally:
mutex.release()
if __name__ == "__main__":
main()
方法6:使用Shell脚本封装
#!/bin/bash
# wrapper.sh - 封装任意命令的互斥运行
LOCKFILE="/tmp/command_lock"
TARGET_COMMAND=$@
if [ -z "$TARGET_COMMAND" ]; then
echo "用法: $0 <命令>"
exit 1
fi
# 尝试获取锁
if [ -f "$LOCKFILE" ]; then
if kill -0 $(cat "$LOCKFILE") 2>/dev/null; then
echo "命令 '$TARGET_COMMAND' 已在运行"
exit 1
fi
fi
echo $$ > "$LOCKFILE"
trap 'rm -f "$LOCKFILE"; exit' EXIT INT TERM
# 执行目标命令
$TARGET_COMMAND
使用建议
-
生产环境推荐:使用
flock(方法2)或锁文件(方法1)
-
防止死锁:添加超时机制
# 带超时的锁文件检查 LOCKFILE="/tmp/app.lock" TIMEOUT=5
等待锁释放(最多等待5秒)
for i in $(seq 1 $TIMEOUT); do if [ -f "$LOCKFILE" ]; then if kill -0 $(cat "$LOCKFILE") 2>/dev/null; then if [ $i -eq $TIMEOUT ]; then echo "等待超时,退出" exit 1 fi sleep 1 else rm -f "$LOCKFILE" break fi else break fi done
3. **日志记录**:添加运行日志
```bash
echo "$(date): 程序启动 (PID: $$)" >> /var/log/app_start.log
选择哪种方法取决于你的具体需求:
- 简单场景:锁文件法
- Linux系统:flock或信号量
- 跨平台需求:Python实现
- 原子操作要求:mkdir法
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播