zoukankan      html  css  js  c++  java
  • python3 进程信号量semaphore

    提前设定好,一个房间只有4个床(计数器现在为4),那么同时只能四个人进来,谁先来的谁先占一个床(acquire,计数器减1),4个床满了之后(计数器为0了),第五个人就要等着,等其中一个人出来(release,计数器加1),他就去占用那个床了。

    互斥锁同时只允许一个线程更改数据,而信号量Semaphore是同时允许一定数量的线程更改数据 。
    假设商场里有4个迷你唱吧,所以同时可以进去4个人,如果来了第五个人就要在外面等待,等到有人出来才能再进去玩。
    实现:
    信号量同步基于内部计数器,每调用一次acquire(),计数器减1;每调用一次release(),计数器加1.当计数器为0时,acquire()调用被阻塞。这是迪科斯彻(Dijkstra)信号量概念P()和V()的Python实现。信号量同步机制适用于访问像服务器这样的有限资源。
    信号量与进程池的概念很像,但是要区分开,信号量涉及到加锁的概念

    # -*- coding: utf-8 -*-
    import os
    import time
    from multiprocessing import Process
    
    def go_ktv(i):
        print("user%s正在....ktv.子进程(%s)" % (i, os.getpid()))
        time.sleep(2)
    
    
    if __name__ == '__main__':
        '''开启20个进程,操作系统可以调度4个cpu去执行,进程的调用比线程的开销大些'''
        start_time = time.time()
        p_lst = []
        for i in range(20):
            p = Process(target=go_ktv, args=(i,))
            p.start()
            p_lst.append(p)
        [pp.join() for pp in p_lst]
        print("运行时间: %s.主进程<%s>" % ((time.time() - start_time), os.getpid()))
    
    # user0正在....ktv.子进程(5496)
    # user1正在....ktv.子进程(6996)
    # user3正在....ktv.子进程(6328)
    # user2正在....ktv.子进程(1064)
    # user4正在....ktv.子进程(4844)
    # user7正在....ktv.子进程(7804)
    # user5正在....ktv.子进程(7688)
    # user8正在....ktv.子进程(7136)
    # user6正在....ktv.子进程(7824)
    # user9正在....ktv.子进程(7812)
    # user10正在....ktv.子进程(8148)
    # user11正在....ktv.子进程(2556)
    # user13正在....ktv.子进程(4744)
    # user15正在....ktv.子进程(6232)
    # user14正在....ktv.子进程(5168)
    # user16正在....ktv.子进程(6444)
    # user12正在....ktv.子进程(2616)
    # user17正在....ktv.子进程(5188)
    # user18正在....ktv.子进程(8088)
    # user19正在....ktv.子进程(7224)
    # 运行时间: 3.2611865997314453.主进程<6936>
    
    

     

    
    
    # -*- coding: utf-8 -*-
    import os
    import time
    from multiprocessing import Pool
    
    
    def go_ktv(i):
        print("user%s正在....ktv.子进程(%s)" % (i, os.getpid()))
        time.sleep(2)
    
    
    if __name__ == '__main__':
        '''创建进程池,进程的容量默认是4,
    如果总进程的数量超过4,就会自动排队等待,一次可执行4个进程,进程池内的进程结束一个,就会自动进来一个新的进程,重用原来的进程号,节省开销
    ''' start_time = time.time() pool = Pool() p_lst = [] for i in range(20): pool.apply_async(go_ktv, args=(i,)) pool.close() pool.join() print("运行时间: %s.主进程<%s>" % ((time.time() - start_time), os.getpid())) # user0正在....ktv.子进程(7396) # user1正在....ktv.子进程(1760) # user2正在....ktv.子进程(8000) # user3正在....ktv.子进程(4120) # user4正在....ktv.子进程(7396) # user5正在....ktv.子进程(1760) # user6正在....ktv.子进程(8000) # user7正在....ktv.子进程(4120) # user8正在....ktv.子进程(7396) # user9正在....ktv.子进程(1760) # user10正在....ktv.子进程(8000) # user11正在....ktv.子进程(4120) # user12正在....ktv.子进程(7396) # user13正在....ktv.子进程(1760) # user14正在....ktv.子进程(8000) # user15正在....ktv.子进程(4120) # user16正在....ktv.子进程(7396) # user17正在....ktv.子进程(1760) # user18正在....ktv.子进程(8000) # user19正在....ktv.子进程(4120) # 运行时间: 10.851620435714722.主进程<7428>
    
    
    
    
    
    # -*- coding: utf-8 -*-
    import os
    import time
    from multiprocessing import Process, Semaphore
    
    def go_ktv(i, sem):
        with sem:
            print("user%s正在....ktv.子进程(%s)" % (i, os.getpid()))
            time.sleep(2)
    
    
    if __name__ == '__main__':
        '''开启20个进程,一次可执行4(信号量容量)个进程,相当于添加另一个互斥锁'''
        start_time = time.time()
        sem = Semaphore(4)
        p_lst = []
        for i in range(20):
            p = Process(target=go_ktv, args=(i, sem))
            p.start()
            p_lst.append(p)
        [pp.join() for pp in p_lst]
        print("运行时间: %s.主进程<%s>" % ((time.time() - start_time), os.getpid()))
    
    # user0正在....ktv.子进程(3660)
    # user1正在....ktv.子进程(7188)
    # user3正在....ktv.子进程(7268)
    # user2正在....ktv.子进程(7568)
    # user5正在....ktv.子进程(2896)
    # user6正在....ktv.子进程(2852)
    # user7正在....ktv.子进程(376)
    # user4正在....ktv.子进程(7532)
    # user9正在....ktv.子进程(8188)
    # user10正在....ktv.子进程(1444)
    # user12正在....ktv.子进程(6304)
    # user11正在....ktv.子进程(6776)
    # user14正在....ktv.子进程(6992)
    # user13正在....ktv.子进程(7248)
    # user8正在....ktv.子进程(6820)
    # user17正在....ktv.子进程(6308)
    # user15正在....ktv.子进程(8020)
    # user18正在....ktv.子进程(4312)
    # user16正在....ktv.子进程(2724)
    # user19正在....ktv.子进程(7516)
    # 运行时间: 10.443597078323364.主进程<2560>
    
    
    
  • 相关阅读:
    信息安全算法
    另类装载问题
    分治法快速排序
    动态规划最长公共子序列
    java网络编程1
    Jndi和会话bean
    EJB初探
    JSF初探
    简单计算器
    关于坐火车
  • 原文地址:https://www.cnblogs.com/lilyxiaoyy/p/10985606.html
Copyright © 2011-2022 走看看