10. 进程锁
如果多个进程同时操作共享数据,可能会导致数据不一致的问题。为了解决这个问题,可以使用进程锁(Lock)来保证同一时间只有一个进程可以访问共享数据。
进程锁示例
下面是一个典型的多进程并发操作文件导致数据不一致的例子:
python
import time
import multiprocessing
def task():
# 假设文件中保存的内容就是一个值: 10
with open("f1.txt", mode="r", encoding="utf-8") as f:
current_num = int(f.read())
print("排队抢票了")
time.sleep(1)
current_num -= 1
with open("f1.txt", mode="w", encoding="utf-8") as f:
f.write(str(current_num))
if __name__ == "__main__":
for i in range(20):
p = multiprocessing.Process(target=task)
p.start()在这个例子中,20 个进程同时读取文件、修改数据并写回。由于没有加锁,多个进程可能同时读到相同的值,导致最终结果不符合预期。
很显然,多进程在操作时就会出现问题,此时就需要锁来介入
使用进程锁解决问题
通过使用 multiprocessing.RLock() 进程锁,可以确保同一时间只有一个进程能够访问共享资源:
python
import time
import multiprocessing
def task(lock):
print("开始")
lock.acquire()
# 假设文件中保存的内容就是一个值: 10
with open("f1.txt", mode="r", encoding="utf-8") as f:
current_num = int(f.read())
print("排队抢票了")
time.sleep(0.5)
current_num -= 1
with open("f1.txt", mode="w", encoding="utf-8") as f:
f.write(str(current_num))
lock.release()
if __name__ == "__main__":
multiprocessing.set_start_method("spawn")
lock = multiprocessing.RLock() # 进程锁
for i in range(10):
p = multiprocessing.Process(target=task, args=(lock,))
p.start()
# spawn模式,需要延迟处理。
time.sleep(7)在这个改进的版本中:
- 创建了一个进程锁
lock = multiprocessing.RLock() - 在访问共享资源前调用
lock.acquire()获取锁 - 访问完成后调用
lock.release()释放锁 - 将锁对象作为参数传递给子进程
这样就能保证同一时间只有一个进程能够读写文件,避免了数据不一致的问题。