zoukankan      html  css  js  c++  java
  • 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出来了
  • 相关阅读:
    Prometheus-node-exporter
    Prometheus基础
    普通函数与回调函数的区别
    HTML转义字符大全
    使用 Chrome DevTools 模拟缓慢的 3G 网络速度
    Chrome 浏览器如何修改 User-Agent
    服务器上的 Git
    Mac配置go环境变量
    Linux和Mac环境变量设置
    Cloudflare DNS设置中子域委派不成功的问题
  • 原文地址:https://www.cnblogs.com/python-daxiong/p/12142716.html
Copyright © 2011-2022 走看看