进程锁(互斥锁)
【一】什么是进程同步(互斥锁)
- 互斥锁(Mutex)是一种用于多线程编程中控制对共享资源访问的机制。
- 其作用是保证在同一时刻只有一个线程在访问共享资源,从而避免多个线程同时读写数据造成的问题。
- 互斥锁的基本原理是在对共享资源进行访问前加锁,使得其他线程无法访问该资源,当访问完成后再解锁,使得其他线程可以进行访问。
- 通过这种方式,可以保证同一时间只有一个线程在执行关键代码段,从而保证了数据的安全性。
- 需要注意的是,互斥锁会带来一些额外的开销,
【二】多个进程共享同一打印终端
- 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的,
- 而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理
【1】未加锁
- 并发运行,效率高,但竞争同一打印终端,带来了打印错乱
# 并发运行,效率高,但竞争同一打印终端,带来了打印错乱
from multiprocessing import Process, Lock
import time
import os
def work(lock):
lock.acquire()
print(f'这是进程:>>>>{os.getpid()} 进程开始')
time.sleep(2)
print(f'这是进程 :>>>> {os.getpid()} 进程结束')
# 走之后把锁放开
lock.release()
if __name__ == '__main__':
lock = Lock()
for i in range(1, 5):
process = Process(target=work,args=(lock,))
process.start()
# 这是进程:>>>>15252 进程开始
# 这是进程 :>>>> 15252 进程结束
# 这是进程:>>>>34436 进程开始
# 这是进程 :>>>> 34436 进程结束
# 这是进程:>>>>39012 进程开始
# 这是进程 :>>>> 39012 进程结束
# 这是进程:>>>>19524 进程开始
# 这是进程 :>>>> 19524 进程结束
# 总结 : 虽然加锁让我们的程序变成了串行,但是对于整个程序来说,安全
# 以时间换空间
【2】多个进程共享同一个文件
import json
# 【一】什么是互斥锁
# 互斥锁(Mutex)是一种用于多进程编程中控制对共享资源访问的机制。
# 其作用是保证在同一时刻只有一个线程在访问共享资源,从而避免多个线程同时读写数据造成的问题。
# 互斥锁的基本原理是在对共享资源进行访问前加锁,使得其他线程无法访问该资源,当访问完成后再解锁,使得其他线程可以进行访问。
# 通过这种方式,可以保证同一时间只有一个线程在执行关键代码段,从而保证了数据的安全性。
# 需要注意的是,互斥锁会带来一些额外的开销,
from multiprocessing import Process, Lock
import time
import os
# 【二】多个进程共享同一打印终端
# 【1】未加锁
'''
def work(lock):
# 进去之前 把门锁起来
lock.acquire()
print(f'这是进程 :>>>> {os.getpid()} 进程开始')
# 模拟 IO 操作
time.sleep(2)
print(f'这是进程 :>>>> {os.getpid()} 进程结束')
# 走之后把锁放开
lock.release()
if __name__ == '__main__':
# 声明一把锁
lock = Lock()
for i in range(1, 5):
process = Process(target=work, args=(lock,))
process.start()
# 总结 : 虽然加锁让我们的程序变成了串行,但是对于整个程序来说,安全
# 以时间换空间
'''
# 【三】多个进程共享同一个文件
'''
BASE_DIR = os.path.dirname(__file__)
file_name = 'data.json'
file_path = os.path.join(BASE_DIR, file_name)
# 【一】初始化票数
def save_data(data=None):
if not data:
data = {'ticket_number': 2}
with open(file_path, mode='w') as fp:
json.dump(data, fp)
# 【二】获取票数信息
def get_ticket_number():
with open(file_path, 'r') as fp:
data = json.load(fp)
return data
# 【三】查看票数
def search_ticket_number(name):
ticket_data = get_ticket_number()
print(f'当前用户 {name} 正在查询余票 {ticket_data.get("ticket_number")} ')
# 【四】买票
def buy_ticket(name):
# 获取票数信息
ticket_data = get_ticket_number()
ticket_number = ticket_data.get("ticket_number")
# 模拟网络延迟
time.sleep(2)
# 【2】买票
if ticket_number > 0:
# 把票买走,减少库存
ticket_data['ticket_number'] -= 1
# 存到文件里
save_data(data=ticket_data)
print(f'当前用户 :>>>> {name} 购票成功!')
else:
print(f"当前用户 :>>>> {name} 已无余票!")
def main(name):
# 【1】先让他查票
search_ticket_number(name=name)
# 【2】买票
buy_ticket(name=name)
if __name__ == '__main__':
save_data()
task_list = []
for i in range(1, 5):
process_obj = Process(target=main, args=(i,))
process_obj.start()
task_list.append(process_obj)
# join 等待
for process_obj in task_list:
process_obj.join()
'''
BASE_DIR = os.path.dirname(__file__)
file_name = 'data.json'
file_path = os.path.join(BASE_DIR, file_name)
# 【一】初始化票数
def save_data(data=None):
if not data:
data = {'ticket_number': 2}
with open(file_path, mode='w') as fp:
json.dump(data, fp)
# 【二】获取票数信息
def get_ticket_number():
with open(file_path, 'r') as fp:
data = json.load(fp)
return data
# 【三】查看票数
def search_ticket_number(name):
ticket_data = get_ticket_number()
print(f'当前用户 {name} 正在查询余票 {ticket_data.get("ticket_number")} ')
# 【四】买票
def buy_ticket(name):
# 获取票数信息
ticket_data = get_ticket_number()
ticket_number = ticket_data.get("ticket_number")
# 模拟网络延迟
time.sleep(2)
# 【2】买票
if ticket_number > 0:
# 把票买走,减少库存
ticket_data['ticket_number'] -= 1
# 存到文件里
save_data(data=ticket_data)
print(f'当前用户 :>>>> {name} 购票成功!')
else:
print(f"当前用户 :>>>> {name} 已无余票!")
def main(name, lock):
# 【1】先让他查票
search_ticket_number(name=name)
# 买票前加锁
lock.acquire()
# 【2】买票
buy_ticket(name=name)
# 买票后释放
lock.release()
if __name__ == '__main__':
save_data()
lock = Lock()
task_list = []
for i in range(1, 5):
process_obj = Process(target=main, args=(i, lock))
process_obj.start()
task_list.append(process_obj)
# join 等待
for process_obj in task_list:
process_obj.join()
标签:__,name,number,互斥,进程,ticket,data
From: https://www.cnblogs.com/Fredette/p/17982377