# #### 锁 lock
from multiprocessing import Process,Lock
上锁和解锁是一对,只上锁不解锁会造成死锁现象(程序发生阻塞,后面代码不执行)
互斥锁:进程之间的相互排斥,谁抢到了资源谁先使用
#创建一把锁
lock = Lock()
#上锁
lock.acquire()
#解锁
lock.release()
<-------------------------------------------------------------------------------->
#模拟12306 抢票软件
from multiprocessing import Process
#读取数据,更新票数
def wr_info(sign,dic = None):
if sign == "r":
with open("ticket",mode = "r",encoding = "utf-8") as fp:
dic = json.load(fp)
return dic
elif sign == "w":
with open("ticket",mode = "w",encoding = "utf-8") as fp:
json.dump(dic,fp)
# 抢票方法
def get_ticket(person):
dic = wr_info("r")
time.sleep(0.5)
if dic["count"] > 0 :
print("%s抢到票了" % (person))
dic["count"] -= 1
wr_info("w",dic)
else:
print("%s没抢到票" % (person))
def run(person,lock):
dic = wr_info("r")
print("%s查询票数,剩余%s张" % (person,dic["count"]))
lock.acquire()
get_ticket(person)
lock.release()
if __name__ == "__main__":
lock = Lock()
lst = ["王振帮思敏","王振1","王振2","王振3","王振4","王振5","王振6","王振7"]
for i in lst:
p = Process(target = run,args = (i,lock))
p.start()
<--------------------------------------------------------------------------------->
# #### 信号量 Semaphore 本质上就是锁,可以控制上锁的数量
sem = Semaphore(4)
sem.acquire()
sem.release()
from multiprocessing import Semaphore, Process
import time, random
def ktv(person, sem):
sem.acquire()
print("%s进入KTV,正在唱歌" % (person))
time.sleep(random.randrange(3, 7))
print("%s离开了KTV,唱完了" % (person))
sem.release()
if __name__ == "__main__":
sem = Semaphore(4)
for i in range(10):
p = Process(target=ktv, args=("person%s" % (i), sem))
p.start()
<------------------------------------------------------------------------------>
# #### 事件 Event
# 阻塞事件 :
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()
print(e.is_set())
e.wait()
print("程序运行中... ")
e = Event()
e.set()
print(e.is_set())
e.wait()
print("程序运行中... ")
e = Event()
e.clear()
print(e.is_set())
e.wait()
print("程序运行中... ")
<---------------------------------------------------------->
# ##模拟红绿灯
import time,random
def traffic_light(e):
print("红灯亮")
while True:
if e.is_set():
time.sleep(1)
print("红灯亮")
e.clear()
else:
time.sleep(1)
print("绿灯亮")
e.set()
def car(e,i):
if not e.is_set():
# 走到这个分支里面来,一定是红灯状态,车要停
print("car%s 在等待" % (i))
e.wait()
print("car%s 通行了" % (i))
if __name__ == "__main__":
lst = []
e = Event()
p1 = Process(target=traffic_light,args=(e,))
p1.daemon = True
p1.start()
# 开始创建小车
for i in range(1,21):
time.sleep(random.randrange(0,2))
p2 = Process(target=car,args=(e,i))
p2.start()
lst.append(p2)
for i in lst:
i.join()
print("程序结束 ... ")
<----------------------------------------------------------------------------->
### ### 进程队列
from multiprocessing import Process,Queue
import queue 是线程队列
特点:先进先出,后进后出
(1)基本语法
q = Queue()
#put 往队列中塞值
q.put(111)
q.put(222)
#get 从队列中取值 --如果没数据了,再调用就一直等待,形成阻塞
res = q.get()
print(res)
# get_nowait() 兼容性问题,在Linux里面有没有值都报错
res = q.get_nowait()
print(res)
# 可以用try except 抛异常
(2)可以限定Queue队列的长度, 超出队列长度就等待,形成阻塞
q1 = Queue(3)
q1.put(1)
q1.put(2)
q1.put(3)
q1.put(4)
res = q1.put_nowait(4)
print(res) # 报错
(3)进程之间通过队列交换数据
def func(q2):
res = q.get()
print(res)
q2.put("刘思敏")
if __name__ == "__main__":
q2 = Queue()
p = Process(target = func,args = (q2,))
p.start()
q2.put("王振")
p.join()
print(q2.get())
<---------------------------------------------------------------------->
### #### 生产者消费者模型
#爬虫例子:
开启多进程:1号进程负责抓取页面中的内容,放入队列中
2号进程负责把内容取出来,配合正则,扣取关键字
1-->生产者 2-->消费者
# 理想模型 是 彼此速度相对均匀
从程序上来说:
生产者负责存储数据(put)
消费者负责获取数据(get)
# 基本模型
from multiprocessing import Process,Queue
#消费者模型
def xiaofeizhe(q,name):
while True:
food = q.get()
time.sleep(random.uniform(0.1,1))
print("%s 吃了一个%s" % (name,food))
#生产者模型
def shengchanzhe(q,name,food):
for i in range(5):
time.sleep(random.uniform(0.1,1))
print("%s生产了%s%s" % (name,food,i))
q.put(food + str(i))
if __name__ == "__main__":
q = Queue()
P = Process(target= xiaofeizhe,args = (q,"刘思敏"))
p.start()
P2 = Process(target= shengchanzhe,args = (q,"王振","黄金"))
p2.start()
# 优化的话,可以生产完后,存入一个None,如果消费者取到了None,就终止消费
<---------------------------------------------------------------------->
# ### 优化生产消费模型 JoinableQueue
from multiprocessing import Process,JoinableQueue
import random,time
put get task_done join
task_done 队列计数减一
task_done 配合join一起使用
put一次,队列计数加一
get一次,队列计数减一
join 函数,会根据队列中的计数器来判断阻塞还是放行
如果计数器是0,意味着放行,否则阻塞
# 消费者模型
def consumer(q,name):
while True:
food = q.get()
time.sleep(random.uniform(0.1,1))
print("%s 吃了一个%s" % (name,food))
q.task_done()
# 生产者模型
def producer(q,name,food):
for i in range(5):
time.sleep(random.uniform(0.1,1))
print("%s 生产了 %s%s" % (name,food,i))
q.put(food+str(i))
if __name__ == "__main__":
jq = JoinableQueue()
p1 = Process(target=consumer,args=(q,"张恒"))
p1.daemon = True
p1.start()
p2 = Process(target=producer,args=(q,"尉翼麟","黄金"))
p2.start()
p2.join()
jq.join()
print("程序结束")
王振2020-6-10笔记
最新推荐文章于 2020-06-28 19:26:16 发布