什么时候用锁?
当多进程同时读写同一份数据,数据可能被破坏
例如:第一个进程写了一个中文字符的一个字节,cpu就切到另外一个进程,另一个今晨也写了一个中文字符的一个字节。
最后文件解码失败
问题之所以出现是因为并发无法控制顺序。
目前可以使用join 来将所有进程的并发改成串行。
锁与join 的区别?
多进程并发的访问了同一资源,将导致资源竞争( 同时读取不会产生问题 同时修改才会产生问题)
第一方案 加上join 单数这样就导致不公平,相当强行规定执行的顺序
第二方法 加锁 谁在cpu分配到资源,谁先处理
相同点:都变成串行
不同点:
1.join顺序固定,锁顺序不固定!
2.join使整个进程的任务全部串行,而锁可以指定哪些代码要串行。
锁是什么
锁的本质上就是一个bool类型的标识符,多进程在执行任务之前会先判断标识符。
互斥锁 两个进程相互排斥。
注意点: 想要锁住资源必须保证,大家拿到是一把锁
怎么使用锁
在需要加锁的地方 lock.acquire() 标识锁定
在代码执行完后,一定要lock.release() 表示释放锁定。
lock.acquire()
放在需要竞争资源的代码(同时写入数据)
lock.release()
基础使用
from multiprocessing import Process,Lock metux = Lock()#生成锁 def task1(lock): lock.acquire()#上锁 for i in range(20): print("========================") lock.release()#释放锁 def task2(lock): lock.acquire() for i in range(20): print("**************************") lock.release() def task3(lock): lock.acquire() for i in range(20): print("???????????????????????????") lock.release() if __name__ == '__main__': p1 = Process(target=task1,args=(metux,))#使用同一把锁才能产生组织其他线程争抢资源的 p2 = Process(target=task2, args=(metux,)) p3 = Process(target=task3, args=(metux,)) p1.start() p2.start() p3.start()
抢票
import json import time import random from multiprocessing import Process,Lock #查看票务的进程 def check_ticket(name): time.sleep(random.randint(1,3)) with open(r'ticket.json',"r",encoding="utf-8") as f: dic = json.load(f) print("%s 查看 当前票数为%s张"%(name,dic["count"])) def buy_ticket(name): with open(r'ticket.json',"r",encoding="utf-8") as f: dic = json.load(f) if dic["count"]>0: dic["count"] -= 1 time.sleep(random.randint(1,3)) with open(r'ticket.json',"w",encoding="utf-8") as f2: dic = json.dump(dic,f2) print("%s购票成功 "%(name)) def run(name,lock): check_ticket(name) lock.acquire() buy_ticket(name) lock.release() if __name__ == '__main__': metux = Lock() for i in range(1,10): name = "顾客%s"%i p = Process(target=run,args=(name,metux)) p.start()