• python 进程同步(锁LOCK,信号量Semaphore,事件Event),生产者消费模型


    1.锁 —— multiprocessing.Lock  

    当多个进程使用同一份数据资源的时候,就会引发数据安全或顺序混乱问题。

    from multiprocessing import Process
    import random
    import time
    
    def func(addr):
        print('我是%s'%addr)
        time.sleep(random.random())
        print('谢谢!')
    
    if __name__ == '__main__':
        l = ['四川的','湖南的','河南的','江苏的']
        for addr in l:
            p = Process(target=func,args=(addr,))
            p.start()
        time.sleep(2)
        print('
    
    我选%s'%random.choice(l))
    # 关于抢占输出资源的事情,是指多进程并发执行时,并不是一个进程执行完任务后其他进程再执行。
    # 比如 此程序会输出:我是四川的  我是河南的 我是江苏的 谢谢!谢谢!我是湖南的 谢谢! 谢谢!
    # 而不是 : 我是四川的 谢谢! 我是河南的 谢谢! ...
    多进程抢占资源
    from multiprocessing import Process ,Lock
    import random
    import time
    
    def func(addr,lock):
        lock.acquire()
        print('我是%s'%addr)
        time.sleep(random.random())
        print('谢谢!')
        lock.release()
    
    if __name__ == '__main__':
        lock = Lock()
        l = ['四川的','湖南的','河南的','江苏的']
        for addr in l:
            p = Process(target=func,args=(addr,lock))
            p.start()
        time.sleep(4)
        print('
    
    我选%s'%random.choice(l))
    使用锁维护输出资源
    from multiprocessing import Process,Lock
    import time
    
    def check(i):
        with open('a') as f :
            num = f.read()
        print('第%s个人在查票,余票为%s' % (i,num))
    
    def buy(i,l):
        l.acquire()
        with open('a') as f :
            num = int(f.read())
            time.sleep(0.1)
        if num >0 :
            print('33[31m 第%s个人买到票了33[0m'%i)
            num -= 1
        else:
            print('33[32m 第%s个人没有买到票33[0m'%i)
        time.sleep(0.1)
        with open('a','w') as f :
            f.write(str(num))
        l.release()
    
    if __name__ == "__main__" :
        l=Lock()
        for i in range(10):
            p_ch = Process(target=check,args=(i+1,))
            p_ch.start()
        for i in range(10):
            p_buy = Process(target=buy,args=(i+1,l))
            p_buy.start()
    例:抢票
    from multiprocessing import Process,Lock,Value
    import time
    
    def get_money(num,l):
        l.acquire()
        for i in range(100):
            num.value -=1
            print(num.value)
            time.sleep(0.01)
        l.release()
    
    def put_money(num,l):
        l.acquire()
        for i in range(100):
            num.value+=1
            print(num.value)
            time.sleep(0.01)
        l.release()
    
    if __name__ =='__main__':
        num =  Value('i',100)
        l = Lock()
        p = Process(target=get_money,args=(num,l))
        p.start()
        p1 = Process(target=put_money, args=(num,l))
        p1.start()
        p.join()
        p1.join()
        print(num.value)
    例:银行存取钱

     2.信号量 —— multiprocessing.Semaphore(了解)      

    上述讲的Lock,属于互斥锁,也就是一把钥匙配备一把锁,同时只允许锁住某一个数据。而信号量则是多把钥匙配备多把锁,也就是说同时允许锁住多个数据。
    
    比如在一个粉红发廊,里边有5位服务人员,那么这个发廊最多就同时允许进入5位客人,当又有第6位客人来的时候,就需要在门外等待;当服务人员服务完某位客人后,才允许后续的人再进来一个,换句话说,这个发廊最多同时接待5位客人,多的客人必须等待。
    
    信号量同步基于内部计数器,用户初始化一个计数器初值(比如上述例子中就初始化为5),每调用一次acquire(),计数器减1;每调用一次release(),计数器加1。当计数器为0时,acquire()调用被阻塞。这是迪科斯彻(Dijkstra)信号量概念P()和V()的Python实现。信号量同步机制适用于访问像服务器这样的有限资源。信号量与进程池的概念很像,但是要区分开,信号量涉及到加锁的概念
    from multiprocessing import Process,Semaphore
    import time
    import random
    
    def func(i,sem):
        sem.acquire()
        print('第%s个人进入小黑屋,拿了钥匙锁上门' % i)
        time.sleep(random.randint(3,5))
        print('第%s个人出去小黑屋,还了钥匙打开门' % i)
        sem.release()
    if __name__ == '__main__' :
        sem =Semaphore(5)
        for i in range(20) :
            p = Process(target=func,args=(i,sem))
            p.start()
    例子

    3.事件 —— multiprocessing.Event(了解)           

    #from multiprocessing import 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 Event, Process
    import time
    
    def tra(e):
        while 1:
            if e.is_set():
                time.sleep(5)
                print('33[31m 红灯亮!33[0m')
                e.clear()
            else:
                time.sleep(5)
                print('33[32m 绿灯亮!33[0m')
                e.set()
    
    
    def Car(i, e):
        e.wait()
        print('第%s辆车过去了' % i)
    
    
    
    if __name__ == '__main__':
        e = Event()
        triff_light = Process(target=tra, args=(e,))
        triff_light.start()
        for i in range(500):
            car = Process(target=Car, args=(i + 1, e,))
            car.start()
            time.sleep(2)
    例:交通信号灯

            

  • 相关阅读:
    Git远程和分支管理
    Git基本使用教程
    linux基础知识总结
    正则表达式-概要
    java注释规范
    JavaScript对象(Object)
    centos7安装docker
    springboot项目问题记录one
    tomcat不需要重启热部署xml文件
    java调用新浪接口根据Ip查询所属地区
  • 原文地址:https://www.cnblogs.com/beihan/p/9513632.html
Copyright © 2020-2023  润新知