day 39(锁,信号量,进程之间的通信,事件,抢票的例子)
锁:
import os
import time
import random
from multiprocessing import Lock # 锁
from multiprocessing import Process
def work(n,lock):
lock.acquire()
print('%s: %s is running' %(n,os.getpid()))
time.sleep(random.random())
print('%s:%s is done' %(n,os.getpid()))
lock.release()
if __name__ == '__main__':
lock = Lock()
for i in range(10):
p=Process(target=work,args=(i,lock))
p.start()
# 同步控制
# 只要用到了锁 锁之内的代码就变成同步的了
# 锁 :控制一段代码 同一时间 只能被一个进程执行
抢票的例子:
import json
import time
import random
from multiprocessing import Process,Lock
def check_ticket(i):
with open('ticket') as f:
ticket_count = json.load(f)
print('person%s查询当前余票 :'%i,ticket_count['count'])
def buy_ticket(i,lock):
check_ticket(i)
lock.acquire()
with open('ticket') as f:
ticket_count = json.load(f)
time.sleep(random.random())
if ticket_count['count'] > 0:
print('person%s购票成功'%i)
ticket_count['count'] -= 1
else:
print('余票不足,person%s购票失败'%i)
time.sleep(random.random())
with open('ticket','w') as f:
json.dump(ticket_count,f)
if __name__ == '__main__':
lock = Lock()
for i in range(10):
Process(target=buy_ticket,args=[i,lock]).start()
信号量:
# KTV 4个房子
import time
import random
from multiprocessing import Process,Semaphore
# def ktv(i,sem):
# sem.acquire()
# print('person %s 进来唱歌了'%i)
# time.sleep(random.randint(1,5))
# print('person %s 从ktv出去了'%i)
# sem.release()
#
# if __name__ == '__main__':
# sem = Semaphore(4)
# for i in range(10):
# Process(target=ktv,args=(i,sem)).start()
# 锁+计数器
# .acquire() 计数器-1
# 计数器减为0 = 阻塞
# .release() 计数器+1
事件:
# 状态
# 子进程 如何 受到状态的影响?
# wait() 的方法 等待 ---> 信号
# 发送信号:通过事件来发送信号
# True set 把信号设置为True
# False clear 把信号设置位False
# 红绿灯 :
# 车 进程 wait() 等红灯
# 根据状态变化 wait遇到True信号,就非阻塞
# 遇到False信号,就阻塞
# 交通灯 进程 红灯 --> False
# 绿灯 --> True
# 事件
# wait的方法 根据一个状态来决定自己是否要阻塞
# 状态相关的方法
# set 将状态改为T
# clear 将状态改为F
# is_set 判断当前的状态是否为T
# from multiprocessing import Event
# # 创建一个事件的对象
# e = Event()
# print(e.is_set()) # 在事件的创世之初,状态为False
# e.set()
# e.wait()
# print(e.is_set())
# e.clear()
# print(e.is_set())
# e.wait()
import time
import random
from multiprocessing import Process,Event
def car(i,e): # 感知状态的变化
if not e.is_set(): # 当前这个事件的状态如果是False
print('car%s正在等待'%i) # 这辆车正在等待通过路口
e.wait() # 阻塞 直到有一个e.set行为 # 等红灯
print('car%s通过路口'%i)
def traffic_light(e): # 修改事件的状态
print('\033[1;31m红灯亮\033[0m')
# 事件在创立之初的状态是False,相当于我程序中的红灯
time.sleep(2) # 红灯亮2s
while True:
if not e.is_set(): # False
print('\033[1;32m绿灯亮\033[0m')
e.set()
elif e.is_set():
print('\033[1;31m红灯亮\033[0m')
e.clear()
time.sleep(2)
if __name__ == '__main__':
e = Event()
Process(target=traffic_light,args=[e,]).start()
for i in range(50):
time.sleep(random.randrange(0,5,2))
Process(target=car,args=[i,e]).start()
进程之间的通信:
# import queue
# # 它能维护一个先进先出的秩序 他不能进行IPC
import time
from multiprocessing import Queue,Process
# 能维护一个先进先出的秩序 也能进行IPC
# def wahaha(q):
# print(q.get())
# q.put('aaa')
#
# if __name__ == '__main__':
# q = Queue()
# Process(target=wahaha,args=[q,]).start()
# q.put(1)
# time.sleep(0.5)
# print(q.get())
# 生产者消费者模型
# 消费者 消费数据 吃包子
# 生产者 产生数据的人 做包子
# 供销矛盾
# 10 供不应求
# 增加做包子的人
# 同步 :做一个包子 卖一包子 吃一包子
# 做包子慢 吃包子快
# 生产数据 买淘宝 ---
# 消费数据 阿里 --- 非常高 必须要快速把用户生产的数据消费完
#
import time
import random
from multiprocessing import Process,Queue
def producer(q):
for i in range(10):
time.sleep(random.random())
q.put('包子%s'%i)
print('\033[1;31m生产了包子%s\033[0m'%i)
def consumer(q):
for i in range(5):
food = q.get()
print(food)
print('\033[1;32m消费了%s\033[0m' %food)
time.sleep(random.uniform(1,2))
if __name__ == '__main__':
q = Queue()
p1 = Process(target=producer,args=[q])
p2 = Process(target=consumer,args=[q])
p3 = Process(target=consumer,args=[q])
p1.start()
p2.start()
p3.start()