进程锁(互斥锁)

进程锁(互斥锁)

【一】什么是进程同步(互斥锁)

  • 互斥锁(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()

__EOF__

本文作者Fredette
本文链接https://www.cnblogs.com/Fredette/p/17982377.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Fredette  阅读(636)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示