王振2020-6-10笔记

# #### 锁  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("程序结束")





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值