day37-进程-锁和信号量

#1、锁:房间的门上有一把锁,锁上有一把钥匙,一个人使用这把钥匙开锁之后,带上钥匙进入房间,把门给反锁了,他在房间干活,
#    只要他不出来还锁,别人是无法进入房间的。同时只能有一个人在房间里干活。效率低,但能保证数据安全。
# 锁 在并发编程中保证数据安全。
#多进程实现并发:多进程就是同时开启多个进程,它们各干各活,从宏观上看跟并发编程是同一个意思。
from multiprocessing import Lock
lock = Lock()                     #创建锁,记住一把锁只有一把钥匙。
lock.acquire()                    #需要锁,拿到了钥匙
lock.acquire()                    #需要锁,但是锁被上面的人拿走了,等别人还锁,所以阻塞了。
lock.release()                    #释放锁,还钥匙

#2、抢票:
# json.load(f):load针对文件句柄,从文件中读取,将string转换为dict。
# json.dump(dict,f):将dict转换为string,写入到文件。
# ticket文件里的字典:{"count":3} ,"count"必须使用双引号,不能使用单引号。
from multiprocessing import Lock
from multiprocessing import Process
import json
def search(i):   #搜索余票,json.load(f)是dict。
    with open('ticket') as f:
        print('客户%s'%i,'查到余票%s'%json.load(f)['count'])

def get(i):    #抢票,json.dump(dict,f)把dict转换为string写入到文件中。
    with open('ticket') as f:
        ticket_count = json.load(f)['count'] #先查出余票的数量。
    if ticket_count > 0:
        with open('ticket','w') as f :
            json.dump({'count':ticket_count-1},f) #抢到票,余票的数量要减1。
        print('客户%s抢到票了'%i)
    else:
        print('客户%s没抢到'%i)

def task(i,lock):     #调用任务task,就可以搜索余票和抢票。
    search(i)         #每个进程都可以搜索余票
    lock.acquire()    #只允许一个进程拿到钥匙,其他进程在等待。
    get(i)            #抢票
    lock.release()    #抢到票之后,还钥匙,这样其他进程才可以拿到钥匙。

if __name__ == '__main__':
    lock = Lock()           #创建锁。
    for i in range(5):     #有5个客户同时在抢票。
        p = Process(target=task,args=(i,lock)) #5个客户相当于5个进程。
        p.start()
# 客户1 查到余票3
# 客户0 查到余票3
# 客户1抢到票了
# 客户0抢到票了
# 客户3 查到余票1
# 客户3抢到票了
# 客户2 查到余票0
# 客户2没抢到
# 客户4 查到余票0
# 客户4没抢到

#3、信号量Semaphore:一把锁可以设置多把钥匙,例如设置3把钥匙,那么同时只能有三个人进入房间,其他人在等待,
#                当房间有人出来,其他人才可以进入。
#以迷你唱吧为例,每次只能进去两个人,其他人在外面等待,有人出来,其他人才能进去。
#信号量本质上就是锁,只不过在锁里面加上了计数器,acquire的时候钥匙的数量减1,release的时候钥匙的数量加1,
#当钥匙的数量为0的时候,其他进程只能等待了。
from multiprocessing import Semaphore
from multiprocessing import Process
import random
import time
def sing(i,sem):
    sem.acquire()                   #拿到钥匙
    print('%s进入房间唱K'%i)
    time.sleep(random.randint(1,10)) #在房间逗留了1到10秒
    print('%s出来了'%i)
    sem.release()                   #还钥匙,有人还钥匙,其他人才能拿到钥匙进入房间。

if __name__ == '__main__':
    sem = Semaphore(2)      #信号量是2,也就是有两把钥匙,每次只能进去两个人,其他人在等待。
    for i in range(5):     #有5个人想唱K
        p = Process(target=sing,args=(i,sem))
        p.start()
# 1进入房间唱K
# 0进入房间唱K
# 1出来了
# 3进入房间唱K
# 0出来了
# 2进入房间唱K
# 3出来了
# 4进入房间唱K
# 2出来了
# 4出来了

猜你喜欢

转载自www.cnblogs.com/python-daxiong/p/12142716.html