
文件锁是一种简单且常用的方法,用于防止多个进程同时访问共享资源。
在 Bash 脚本中,可以使用 flock 命令实现文件锁:
#!/bin/bash
# 定义锁文件
LOCKFILE="/var/lock/my_script.lock"
# 使用 flock 创建排他锁
(
flock -x 200
# 关键代码段
echo "脚本开始运行"
sleep 10 # 模拟耗时操作
echo "脚本结束运行"
) 200>"$LOCKFILE"flock -x 200 表示获取一个排他锁。200 绑定到 $LOCKFILE,确保锁的作用范围。在 Python 中,可以使用 fcntl 模块实现文件锁:
import fcntl
import time
# 定义锁文件
lock_file = open("/var/lock/my_script.lock", "w")
try:
# 获取排他锁
fcntl.flock(lock_file, fcntl.LOCK_EX)
print("脚本开始运行")
time.sleep(10) # 模拟耗时操作
print("脚本结束运行")
finally:
# 释放锁
fcntl.flock(lock_file, fcntl.LOCK_UN)
lock_file.close() 信号量是一种更高级的同步机制,适用于复杂的并发场景。
在 Python 中,可以使用 threading.Semaphore 或 multiprocessing.Semaphore 实现信号量:
import threading
import time
# 定义信号量
semaphore = threading.Semaphore(1)
def critical_section():
semaphore.acquire()
try:
print("进入关键代码段")
time.sleep(5) # 模拟耗时操作
print("退出关键代码段")
finally:
semaphore.release()
# 模拟并发执行
threads = [threading.Thread(target=critical_section) for _ in range(5)]
for t in threads:
t.start()
for t in threads:
t.join() 如果共享资源存储在数据库中,可以通过数据库事务来避免竞争条件。
假设您使用的是 MySQL 数据库,可以通过事务确保操作的原子性:
START TRANSACTION;
-- 更新共享资源
UPDATE resource_table SET value = value + 1 WHERE id = 1;
COMMIT;结合 SQLAlchemy 使用事务:
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
# 创建数据库连接
engine = create_engine("mysql+pymysql://user:password@host/dbname")
Session = sessionmaker(bind=engine)
session = Session()
try:
# 开始事务
session.begin()
# 更新共享资源
resource = session.execute("SELECT * FROM resource_table WHERE id = 1 FOR UPDATE").fetchone()
session.execute("UPDATE resource_table SET value = value + 1 WHERE id = 1")
# 提交事务
session.commit()
except Exception as e:
# 回滚事务
session.rollback()
print(f"发生错误: {e}")
finally:
session.close() 如果不需要完全并行执行,可以通过限制并发数来避免竞争条件。
使用 pgrep 和 wc -l 检查当前运行的脚本实例数:
#!/bin/bash
# 最大并发数
MAX_CONCURRENT=1
# 检查当前运行的实例数
current_running=$(pgrep -fc "$(basename $0)" || true)
if [ "$current_running" -ge "$MAX_CONCURRENT" ]; then
echo "已有 $current_running 个实例运行,退出"
exit 1
fi
# 脚本逻辑
echo "脚本开始运行"
sleep 10 # 模拟耗时操作
echo "脚本结束运行"使用 concurrent.futures 限制并发数:
from concurrent.futures import ThreadPoolExecutor
import time
def task():
print("任务开始")
time.sleep(5) # 模拟耗时操作
print("任务结束")
# 最大并发数
MAX_WORKERS = 2
with ThreadPoolExecutor(max_workers=MAX_WORKERS) as executor:
futures = [executor.submit(task) for _ in range(5)]
for future in futures:
future.result() 原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。