【第51天】python全栈从入门到放弃

2019-08-11  本文已影响0人  36140820cbfd

1锁机制

l = Lock() 实例化
一把锁配一把钥匙
拿钥匙,锁门 l.acquire()
还钥匙,开门 l.release()

代码块
from multiprocessing import Lock

l = Lock()

l.acquire()# 拿走钥匙,锁门,不让其他人进屋

l.release()# 释放锁。  还钥匙,开门,允许其他人进屋

2 模拟12306买火车票(锁)

代码块
from multiprocessing import Process,Lock
import time

def check(i):
    with open('余票') as f:
        con = f.read()
    print('第%s个人查到余票还剩%s张'%(i,con))

def buy_ticket(i,l):
    l.acquire()# 拿钥匙,锁门
    with open('余票') as f:
        con = int(f.read())
        time.sleep(0.1)
    if con > 0:
        print('\033[31m 第%s个人买到票了\033[0m'%i)
        con -= 1
    else:
        print('\033[32m 第%s个人没有买到票\033[0m'%i)
    time.sleep(0.1)# 是指 买完票后,把余票数量重写写入数据库的时间延迟
    with open('余票','w') as f:
        f.write(str(con))
    l.release()# 还钥匙,开门

if __name__ == '__main__':
    l = Lock()
    for i in range(10):
        p_ch = Process(target=check,args=(i+1,))
        p_ch.start()
    for i in range(10):
        p_buy = Process(target=buy_ticket,args=(i+1,l))
        p_buy.start()

3信号机制

sem = Semaphore(n)
n : 是指初始化一把锁配几把钥匙,一个int型
拿钥匙,锁门 l.acquire()
还钥匙,开门 l.release()
信号量机制比锁机制多了一个计数器,这个计数器是用来记录当前剩余几把钥匙的。
当计数器为0时,表示没有钥匙了,此时acquire()处于阻塞。
对于计数器来说,每acquire一次,计数器内部就减1,release一次,计数器就加1

4 信号机制例子:

代码块
from multiprocessing import Semaphore,Lock

l = Lock()
l.acquire()
print(123)
l.release()   #使用Lock存在问题,每次只能只用1个,必须release释放才能继续,好在有semaphore()
l.acquire()
print(456)


l = Semaphore(4)

l.acquire()# 拿走1把钥匙,锁上门
print(123)
l.acquire()# 拿走1把钥匙,锁上门
print(456)
l.acquire()# 拿走1把钥匙,锁上门
print(789)
l.acquire()# 拿走1把钥匙,锁上门
print(120)

5 信号机制:发廊服务

代码块
from multiprocessing import Process,Semaphore
import time
import random

def func(i,sem):
    sem.acquire()
    print('第%s个人进入小黑屋,拿了钥匙锁上门' % i)
    time.sleep(random.randint(3,5))
    print('第%s个人出去小黑屋,还了钥匙打开门' % i)
    sem.release()

if __name__ == '__main__':
    sem = Semaphore(5)# 初始化了一把锁5把钥匙,也就是说允许5个人同时进入小黑屋
    # 之后其他人必须等待,等有人从小黑屋出来,还了钥匙,才能允许后边的人进入
    for i in range(20):
        p = Process(target=func,args=(i,sem,))
        p.start()

6,事件机制

e = Event() 实例化一个事件
e.set() #将is_set()设为True
e.clear() # 将is_set()设为False
e.wait() #判断is_set的bool值,如果bool为True,则非阻塞,bool值为False,则阻塞
e.is_set() # 标识

事件是通过is_set()的bool值,去标识e.wait() 的阻塞状态
当is_set()的bool值为False时,e.wait()是阻塞状态
当is_set()的bool值为True时,e.wait()是非阻塞状态
当使用set()时,是把is_set的bool变为True
当使用clear()时,是把is_set的bool变为False

所以,事件是什么呢,事件就是通过set()和clear()控制is_set()的布尔值(True/False),进而控制wait()的阻塞状态

7 事件的举例

代码块
from multiprocessing import Event

e = Event()

print(e.is_set())# False wait应该是阻塞住,默认
e.set()# 将is_set 的bool值变为True,将wait变为非阻塞
e.wait()
print(e.is_set())
print(123)
e.clear()
print(e.is_set())
e.wait()
print(123)

8. 信号灯的模拟

代码块
from multiprocessing import Process,Event
import time
import random

def tra(e):

    while 1:# 红绿灯得一直亮着,要么是红灯要么是绿灯
        if e.is_set():# True,代表绿灯亮,那么此时代表可以过车
            time.sleep(5)# 所以在这让灯等5秒钟,这段时间让车过
            print('\033[31m 红灯亮! \033[0m')# 绿灯亮了5秒后应该提示到红灯亮
            e.clear()# 把is_set设置为False
        else:
            time.sleep(5)# 此时代表红灯亮了,此时应该红灯亮5秒,在此等5秒
            print('\033[32m 绿灯亮! \033[0m')# 红的亮够5秒后,该绿灯亮了
            e.set()# 将is_set设置为True

def Car(i,e):
    e.wait()# 车等在红绿灯,此时要看是红灯还是绿灯,如果is_set为True就是绿灯,此时可以过车
    print('第%s辆车过去了'%i)

if __name__ == '__main__':
    e = Event()
    triff_light = Process(target=tra,args=(e,))# 信号灯的进程
    triff_light.start()
    for i in range(500):# 描述50辆车的进程
        car = Process(target=Car,args=(i+1,e,))
        car.start()
别跑,点个赞再走
上一篇 下一篇

猜你喜欢

热点阅读