应用在多进程中
互斥所lock:互斥锁是进程间的get_ticket互相排斥
进程之间,谁先枪占到资源,谁就先上锁,等到解锁之后,下一个进程在继续使用。
# 语法:
上锁: lock.acquire()
解锁: lock.release()
(1)基本语法
from multiprocessing import Process,Lock lock = Lock() # 上锁 lock.acquire() print(1) # lock.release() # 如果不解锁,2 就不会打印。 lock.acquire() print(2) lock.release()
(2)模拟抢票
from multiprocessing import Process import json def wr_info(sign,dic=None): if sign == "r": with open("ticket.txt" ,mode="r",encoding="utf-8")as fp: dic = json.load(fp) return dic elif sign == "w": with open("ticket.txt",mode="w",encoding="utf-8")as fp: json.dump(dic,fp) # 抢票的方法 def get_ticket(person): # 读取数据库中的实际票数 dic = wr_info("r") time.sleep(0.1) if dic["count"] > 0: print("%s 抢票成功 !!"%(person)) dic["count"] -= 1 # 更新数据库 wr_info("w",dic) else: print("%s抢票失败"%(person)) # get_ticket("zhangsan") # 用ticket来进行统一的函数调用 def ticket(person,lock): # 查询票数 dic = wr_info("r") print("%s查询票数是%s"%(person,dic["count"])) # 遇到了acquire上锁之后,进程之间变成同步 lock.acquire() # 开始签票 get_ticket(person) lock.release() if __name__ == ‘__main__‘: lock = Lock() for i in range(5): p = Process(target=ticket,args=("person%s"%(i),lock)) p.start()
(3)区分同步和异步
from multiprocessing import Process def func(num,lock): # 同步上锁 lock.acquire() print(num) lock.release() if __name__ == "__main__": lock = Lock() for i in range(10): # 异步并发 p = Process(target=func,args=(i,lock)) p.start()
本质上就是锁,同一时间可以上多把锁
# 语法:
sem = Semaphone(3)
sem.acquire()
sem.release()
(1)基本用法
import time import random from multiprocessing import Process,Semaphore def ktv(person,sem): sem.acquire() print("%s进入了ktv,正在唱歌"%(person)) time.sleep(random.randrange(3,6)) print("%s唱完了,离开了ktv"%(person)) sem.release() if __name__ == "__main__": sem = Semaphore(3) for i in range(10): p = Process(target=ktv,args=("person%s"%(i),sem)) p.start()
注意:
lock 多个进程之间,一次只能上一把锁
Semaphore 多个进程之间,可以自定义上锁的数量,不限于一个
# 阻塞事件
e = Event()生成事件对象e
e.wait()动态给程序加阻塞,程序当中是否加阻塞完全取决与该对象中的is_set()[默认返回值是False]
# 如果是True,不加阻塞
# 如果是False 加阻塞
#控制这个属性的值
# set()方法 将这个属性的值改成True
# clear()方法 将这个属性的值改成False
# is_set()方法 判断当前的属性是否为True (默认上来是False)
(1)基本语法
from multiprocessing import Process,Event e = Event() # 实例化,生成对象e print(e.is_set()) # 查看对象e中的is_set()是True还是False。默认是False e.wait() # 加阻塞。is_set()是False print(1) # (2) e = Event() e.set() # 将is_set() 改成True e.wait() # 不加阻塞 print(3) e.clear() # 把True=>False e.wait() print(444)
(2)红绿灯
import time,random from multiprocessing import Process,Event def traffic_light(e): # 默认红灯亮 print("红灯亮") while True: if e.is_set(): # 让绿灯亮1秒钟 time.sleep(1) #切换红灯亮 print("红灯亮") # 把True改成False e.clear() else: # 让红灯亮1秒钟 time.sleep(1) # 切换成绿灯亮 print("绿灯亮") # 把默认值从False改成True e.set() def car(e,i): # 判断如果是红灯亮,就执行下面代码 if not e.is_set(): print("car%s 在等待"% (i)) e.wait() print("car%s通行了"%(i)) """ # 方法一 if __name__ == "__main__": e = Event() # 创建交通灯对象 p1 = Process(target=traffic_light,args=(e,)) p1.start() # 创建小车 for i in range(10): time.sleep(random.randrange(0,2)) p2 = Process(target=car,args=(e,i)) p2.start() """ # 方法二: 优化红绿灯代码[当小车执行结束的时候,把红绿灯终止] if __name__ == ‘__main__‘: lst = [] e = Event() # 创建交通灯对象 p1 = Process(target=traffic_light,args=(e,)) p1.daemon=True p1.start() # 创建小车 for i in range(20): time.sleep(random.randrange(0,2)) p2 = Process(target=car,args=(e,i)) p2.start() # 等所有小车通行之后,关闭守护程序 for i in lst: i.join() print("主程序执行结束。。。")
原文:https://www.cnblogs.com/youhongliang/p/11862862.html