• python-- 信号量 Semphore、事件 Event


    信号量 Semphore

    sem=Semphore(n):n是指初始化一把锁配几把钥匙,一个int型

    拿钥匙,锁门 sem.acquire()

    还钥匙,开门 sem.release()

    信号量机制比锁机制多了一个计数器,这个计数器是用来计录当前剩几把钥匙的。当计数器为0时,表示没有钥匙了,此时acquire()处于阻塞。

    对于计数器来说,每acquire一次,计数器内部就减1,release一次,计数器就加1

    from multiprocessing import Process, Semaphore
    
    l = Semaphore(3)  # 实例化,传一个int型的值
    
    l.acquire()  # 拿走1把钥匙,锁上门
    print(12)
    l.acquire()  # 拿走1把钥匙,锁上门
    print(34)
    l.acquire()  # 拿走1把钥匙,锁上门
    print(56)
    l.acquire()  # 拿走1把钥匙,锁上门
    print(78)

    结果:

    12
    34
    56
    # 只有三把钥匙,当遇到第四个l.acquire()时就阻塞了

    释放锁

    from multiprocessing import Process, Semaphore
    
    l = Semaphore(3)  # 实例化,传一个int型的值
    
    l.acquire()  # 拿走1把钥匙,锁上门
    print(12)
    l.acquire()  # 拿走1把钥匙,锁上门
    print(34)
    l.acquire()  # 拿走1把钥匙,锁上门
    print(56)
    l.release()  # 释放钥匙
    l.acquire()  # 拿走1把钥匙,锁上门
    print(78)

    结果

    12
    34
    56
    78

    案例

    from multiprocessing import Process, Semaphore
    import time
    import random
    
    
    def func(i, sem):
        sem.acquire()
        print('第%s个人进入小黑屋,拿了钥匙锁上门' % i)
        time.sleep(2)
        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()

    结果:

    第0个人进入小黑屋,拿了钥匙锁上门
    第1个人进入小黑屋,拿了钥匙锁上门
    第2个人进入小黑屋,拿了钥匙锁上门
    第3个人进入小黑屋,拿了钥匙锁上门
    第4个人进入小黑屋,拿了钥匙锁上门
    第0个人出去小黑屋,还了钥匙打开门
    第1个人出去小黑屋,还了钥匙打开门
    第5个人进入小黑屋,拿了钥匙锁上门
    第6个人进入小黑屋,拿了钥匙锁上门
    第2个人出去小黑屋,还了钥匙打开门第3个人出去小黑屋,还了钥匙打开门
    
    第7个人进入小黑屋,拿了钥匙锁上门
    第8个人进入小黑屋,拿了钥匙锁上门
    第4个人出去小黑屋,还了钥匙打开门
    第9个人进入小黑屋,拿了钥匙锁上门
    第5个人出去小黑屋,还了钥匙打开门
    第6个人出去小黑屋,还了钥匙打开门
    第10个人进入小黑屋,拿了钥匙锁上门
    第11个人进入小黑屋,拿了钥匙锁上门
    第7个人出去小黑屋,还了钥匙打开门
    第8个人出去小黑屋,还了钥匙打开门
    第9个人出去小黑屋,还了钥匙打开门
    第12个人进入小黑屋,拿了钥匙锁上门
    第13个人进入小黑屋,拿了钥匙锁上门
    第14个人进入小黑屋,拿了钥匙锁上门
    第10个人出去小黑屋,还了钥匙打开门第11个人出去小黑屋,还了钥匙打开门
    
    第14个人出去小黑屋,还了钥匙打开门第12个人出去小黑屋,还了钥匙打开门
    
    第13个人出去小黑屋,还了钥匙打开门
    第17个人进入小黑屋,拿了钥匙锁上门
    第18个人进入小黑屋,拿了钥匙锁上门第15个人进入小黑屋,拿了钥匙锁上门
    
    第19个人进入小黑屋,拿了钥匙锁上门第16个人进入小黑屋,拿了钥匙锁上门
    
    第18个人出去小黑屋,还了钥匙打开门第15个人出去小黑屋,还了钥匙打开门第17个人出去小黑屋,还了钥匙打开门
    
    
    第19个人出去小黑屋,还了钥匙打开门
    第16个人出去小黑屋,还了钥匙打开门

    事件 Event

    e = Event()
    e.set()
    e.clear()
    e.wait()
    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

    红绿灯案例

    from multiprocessing import Process, Event
    import time
    
    
    def lighter(l):
        count = 0
        l.set()  # 先设置绿灯
        while True:
            if count > 5 and count < 10:
                l.clear()  # 把标志位清了,改为红 灯
                print('33[41;1m  red light  ...33[0m')
            elif count > 10:
                l.set()  # 变绿灯
                count = 0
            else:
                print('33[42;1m green light...33[0m')
            time.sleep(1)
            count += 1
    
    
    def car(name, l):
        while True:
            if l.is_set():  # 判断标志位是否存在
                print('[%s] runing' % name)
                time.sleep(1)
            else:
                print('[%s] sees red light,waiting...' % name)
                l.wait()  # 等待标志位设定
                print('33[34;1m[%s] green light is on,start going...33[0m' % name)
    
    
    if __name__ == '__main__':
        l = Event()
        light = Process(target=lighter, args=(l,))
        light.start()
        car1 = Process(target=car, args=('BMW', l))
        car1.start()

  • 相关阅读:
    今天博客开通第一天,以此纪念!
    基于opencv的车牌识别系统
    【C和指针】笔记1
    【局域网聊天客户端篇】基于socket与Qt
    对Qt下对话服务器客户端的总结(MyTcpServer与MyTcpClient)
    linux 线程编程详解
    【linux】安装samba服务
    linux(ubuntu)获取命令源码方式
    win7下用SSH连接linux虚拟机
    Linux下deb包安装工具(附带安装搜狗输入法)
  • 原文地址:https://www.cnblogs.com/zouzou-busy/p/13775325.html
Copyright © 2020-2023  润新知