zoukankan      html  css  js  c++  java
  • 五. 并发编程 (进程信号量)

    一. 进程信号量( multiprocessing.Semaphore

    1. 信号量概念(相当于在锁的基础上增加计数器)

    锁的概念一样 ,只不过可以设置钥匙的数量
    上述讲的Lock,属于互斥锁,也就是一把钥匙配备一把锁,同时只允许锁住某一个数据。而信号量则是多把钥匙配备多把锁,也就是说同时允许锁住多个数据。
    比如在一个粉红发廊,里边有5位服务人员,那么这个发廊最多就同时允许进入5位客人,当又有第6位客人来的时候,就需要在门外等待;当服务人员服务完某位客人后,
    才允许后续的人再进来一个,换句话说,这个发廊最多同时接待5位客人,多的客人必须等待。 信号量同步基于内部计数器,用户初始化一个计数器初值(比如上述例子中就初始化为5)每调用一次acquire(),计数器减1;每调用一次release(),计数器加1。
    当计数器为0时,acquire()调用被阻塞。这是迪科斯彻(Dijkstra)信号量概念P()和V()的Python实现。信号量同步机制适用于访问像服务器这样的有限资源。
    信号量与进程池的概念很像,但是要区分开,信号量涉及到加锁的概念

    2. multiprocessing.Semaphore

    import time
    import random
    from multiprocessing import Process
    from multiprocessing import Semaphore
    
    aa=Semaphore(4)
    aa.acquire()
    print("第一把钥匙")
    aa.acquire()
    print("第二把钥匙")
    aa.acquire()
    print("第三把钥匙")
    aa.acquire()
    print("第四把钥匙")
    aa.acquire()
    print("第五把钥匙")   # 不打印
    #
    # 第一把钥匙
    # 第二把钥匙
    # 第三把钥匙
    # 第四把钥匙
    import time
    import random
    from multiprocessing import Process
    from multiprocessing import Semaphore
    
    def fn(i, sem):
        sem.acquire()  # 拿钥匙
        print('%s拿到钥匙!!!!!!' % (i))
        time.sleep(random.randint(1, 5))
        print('%s归还钥匙-----' % (i))
        sem.release()  # 还钥匙
    
    if __name__ == '__main__':
        sem = Semaphore(4) #  也是同步  和锁的概念一样
        for i in range(3):
            p = Process(target=fn, args=(i, sem))
            p.start()
    sem = Semaphore(4)
    sem.acquire()
    print('第一个人')
    sem.acquire()
    print('第二个人')
    sem.acquire()
    print('第三个人')
    sem.acquire()
    print('第四个人')
    sem.acquire()
    print('第五个人')  # 第五个无法打印
    # 因为只有四把钥匙,只能有四个进程进去 , 当前进程时第五个 所有进不去
    
    # 执行结果
        第一个人
        第二个人
        第三个人
        第四个人
        第一个人
        第二个人
        第三个人
        第四个人
        第一个人
        第二个人
        第三个人
        第四个人
        第一个人
        第二个人
        第三个人
        第四个人
    import time
    import random
    from multiprocessing import Process
    from multiprocessing import Semaphore
    
    def fn(i, sem):
        sem.acquire()  # 拿钥匙
        print('%s拿到钥匙!!!!!!' % (i))
        time.sleep(random.randint(1, 5))
        print('%s归还钥匙-----' % (i))
        sem.release()  # 还钥匙
    
    if __name__ == '__main__':
        sem = Semaphore(4) #  也是同步  和锁的概念一样
        for i in range(10):
            p = Process(target=fn, args=(i, sem))
            p.start()
    
    #
    # 0拿到钥匙!!!!!!
    # 1拿到钥匙!!!!!!
    # 2拿到钥匙!!!!!!
    # 3拿到钥匙!!!!!!
    # 1归还钥匙-----
    # 4拿到钥匙!!!!!!
    # 0归还钥匙-----
    # 6拿到钥匙!!!!!!
    # 2归还钥匙-----
    # 5拿到钥匙!!!!!!
    # 3归还钥匙-----
    # 7拿到钥匙!!!!!!
    # 4归还钥匙-----
    # 8拿到钥匙!!!!!!
    # 5归还钥匙-----
    # 9拿到钥匙!!!!!!
    # 6归还钥匙-----
    # 7归还钥匙-----
    # 9归还钥匙-----
    # 8归还钥匙-----
  • 相关阅读:
    HDU 3729【二分匹配】
    51nod 1456【强连通,缩点,并查集】
    51nod1459【二级最短路】
    51nod1640 【最小生成树】
    CodeForces660B【模拟—水】
    CodeForces691C 【模拟】
    Codeforces698B【并查集+拆环】
    CodeForces717C 【数学】
    Codeforces710C【数学】
    HDU5904【瞎搞】
  • 原文地址:https://www.cnblogs.com/Sup-to/p/11188101.html
Copyright © 2011-2022 走看看