zoukankan      html  css  js  c++  java
  • 4月25日 python学习总结 互斥锁 IPC通信 和 生产者消费者模型

    一、守护进程  

    import random
    import time
    from multiprocessing import  Process
    
    def task():
        print('name: egon')
        time.sleep(random.randint(0,3))
        print('sex:male')
        time.sleep(random.randint(0, 3))
        print('age:19')
    
    
    if __name__ == '__main__':
          p=Process(target=task)
          p.daemon()   #将p设置为主进程的守护进程,主进程结束,无论子进程是否正常执行完,都跟主进程一起结束

    二、互斥锁

     互斥锁:
    强调:必须是lock.acquire()一次,然后 lock.release()释放一次,才能继续lock.acquire(),不能连续的lock.acquire()

     互斥锁vs join的区别:

        大前提:

        二者的原理都是一样,都是将并发变成串行,从而保证有序

     

       区别:

     一、join是按照人为指定的顺序执行,而互斥锁是所以进程平等地竞争,谁先抢到谁执行
     二、 互斥锁可以让一部分代码(修改共享数据的代码)串行,而join只能将代码整体串行

     1 from multiprocessing import Process,Lock
     2 import time,random
     3 
     4 mutex=Lock()
     5 # 互斥锁:
     6 #强调:必须是lock.acquire()一次,然后 lock.release()释放一次,才能继续lock.acquire(),不能连续的lock.acquire()
     7 
     8 # 互斥锁vs join的区别一:
     9 # 大前提:二者的原理都是一样,都是将并发变成串行,从而保证有序
    10 # 区别:# 互斥锁vs join的区别:
    11 # 大前提:二者的原理都是一样,都是将并发变成串行,从而保证有序
    12 # 区别:一、join是按照人为指定的顺序执行,而互斥锁是所以进程平等地竞争,谁先抢到谁执行
    13 #    二、 互斥锁可以让一部分代码(修改共享数据的代码)串行,而join只能将代码整体串行
    14 
    15 def task1(lock):
    16     lock.acquire()          #抢锁
    17     print('task1:名字是egon')
    18     time.sleep(random.randint(1,3))
    19     print('task1:性别是male')
    20     time.sleep(random.randint(1,3))
    21     print('task1:年龄是18')
    22     lock.release()          #释放锁
    23 
    24 def task2(lock):
    25     lock.acquire()
    26     print('task2:名字是alex')
    27     time.sleep(random.randint(1,3))
    28     print('task2:性别是male')
    29     time.sleep(random.randint(1,3))
    30     print('task2:年龄是78')
    31     lock.release()
    32 
    33 
    34 def task3(lock):
    35     lock.acquire()
    36     print('task3:名字是lxx')
    37     time.sleep(random.randint(1,3))
    38     print('task3:性别是female')
    39     time.sleep(random.randint(1,3))
    40     print('task3:年龄是30')
    41     lock.release()
    42 
    43 
    44 
    45 if __name__ == '__main__':
    46     p1=Process(target=task1,args=(mutex,))
    47     p2=Process(target=task2,args=(mutex,))
    48     p3=Process(target=task3,args=(mutex,))
    49 
    50     # p1.start()
    51     # p1.join()
    52     # p2.start()
    53     # p2.join()
    54     # p3.start()
    55     # p3.join()
    56 
    57     p1.start()
    58     p2.start()
    59     p3.start()
    互斥锁应用

     

     1 from multiprocessing import  Process,Lock
     2 import time,json,random,os
     3 
     4 lock=Lock()
     5 def search():
     6     print('========%s 查票======' % os.getpid())
     7     info=json.load(open('test.txt'))
     8     msg='余票为: %s'%info['count']
     9     print(msg)
    10 
    11 def get(lock):
    12     lock.acquire()
    13     print('========%s 抢票======'%os.getpid())
    14     info = json.load(open('test.txt'))
    15     time.sleep(random.random())
    16     if info['count']>0:
    17         info['count']-=1
    18         time.sleep(random.random())
    19         json.dump(info,open('test.txt','w'))
    20         print('抢票成功')
    21     else:
    22         print('票已售完')
    23     lock.release()
    24 
    25 def op(lock):
    26     search()
    27     get(lock)
    28 
    29 if __name__ == '__main__':
    30     for i in range(0,50):
    31         p=Process(target=op,args=(lock,))
    32         p.start()
    模拟抢票系统

     

    三、IPC通信(进程之间的的通信控制)  

    进程之间通信必须找到一种介质,该介质必须满足

    • 是所有进程共享的
    • 必须是内存空间
    • 附加:帮我们自动处理好锁的问题

    1、队列(推荐使用)     

    • 共享的空间
    • 是内存空间
    • 自动帮我们处理好锁定问题

      强调:
         1、队列用来存成进程之间沟通的消息,数据量不应该过大
         2、maxsize的值超过的内存限制就变得毫无意义

    from multiprocessing import Queue
    
    q=Queue(3)    #创建队列,并为队列设置大小 此处为3
    q.put('first')
    q.put({'second':None})      #可以存放任意类型
    q.put('')
    
    # q.put(4)      #队列存满,第四个存不进,阻塞,等待别的进程取出队列中内容
    
    print(q.get())
    print(q.get())
    print(q.get())
    print(q.get())   # 阻塞 ,队列为空,取不出东西,等待其他进程往队列中存放东西
    p.put('first',block=False,timeout=4)
    p.get('first',block=False,timeout=4)
    
    #第一个参数 是存放到队列中的数据
    #第二个参数block ,是否进入阻塞状态,当队满存值或队空取值时,默认值为True
    #第三个参数timeout ,当队满存值或队空取值时,阻塞等待的时间,若超过时间则报错

     

    2、Manager

    没有处理好锁问题,不推荐使用 

    from multiprocessing import Process,Manager,Lock
    import time
    
    mutex=Lock()
    
    def task(dic,lock):
        lock.acquire()
        temp=dic['num']
        time.sleep(0.1)
        dic['num']=temp-1
        lock.release()
    
    if __name__ == '__main__':
        m=Manager()          #创建一个共享空间
        dic=m.dict({'num':10})
    
        l=[]
        for i in range(10):
            p=Process(target=task,args=(dic,mutex))
            l.append(p)
            p.start()
    
        for p in l:
            p.join()
        print(dic)

        

      3、管道(不推荐使用)

    • 是所有进程共享的
    • 是内存空间
    • 两头存取数据
    • 没有帮我们自动处理好锁的问题

     

    四、生产者消费者模型  

    该模型中包含两类重要的角色:

    1、生产者:将负责造数据的任务比喻为生产者
    2、消费者:接收生产者造出的数据来做进一步的处理,该类人物被比喻成消费者


    实现生产者消费者模型三要素

    1、生产者
    2、消费者
    3、队列

    什么时候用该模型:

    程序中出现明显的两类任何,一类任务是负责生产,另外一类任务是负责处理生产的数据的

    该模型的好处:

    1、实现了生产者与消费者解耦和
    2、平衡了生产力与消费力,即生产者可以一直不停地生产,消费者可以不停地处理,因为二者
    不再直接沟通的,而是跟队列沟通

     1 import time
     2 import random
     3 from multiprocessing import Process,Queue
     4 
     5 def consumer(name,q):
     6     while True:
     7         res=q.get()
     8         time.sleep(random.randint(1,3))
     9         print('33[46m消费者===》%s 吃了 %s33[0m' %(name,res))
    10 
    11 
    12 def producer(name,q,food):
    13     for i in range(5):
    14         time.sleep(random.randint(1,2))
    15         res='%s%s' %(food,i)
    16         q.put(res)
    17         print('33[45m生产者者===》%s 生产了 %s33[0m' %(name,res))
    18 
    19 
    20 if __name__ == '__main__':
    21     #1、共享的盆
    22     q=Queue()
    23 
    24     #2、生产者们
    25     p1=Process(target=producer,args=('egon',q,'包子'))
    26     p2=Process(target=producer,args=('刘清政',q,'泔水'))
    27     p3=Process(target=producer,args=('杨军',q,'米饭'))
    28 
    29     #3、消费者们
    30     c1=Process(target=consumer,args=('alex',q))
    31     c2=Process(target=consumer,args=('梁书东',q))
    32 
    33 
    34     p1.start()
    35     p2.start()
    36     p3.start()
    37     c1.start()
    38     c2.start()
    生产者消费者模式
  • 相关阅读:
    1.2 文本域(含可编辑表格实现)
    JS手册目录
    1.1 文本框
    JS传中文到后台需要的处理
    java基础和面向对象面试题_01
    try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?
    java面试题:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
    java基础学习_IO流04_用户登录注册案例(IO版)、数据操作流(操作基本数据类型的流)、内存操作流、打印流、标准输入输出流、随机访问流、合并流、序列化流(对象操作流)、Properties属性集合类、NIO(新IO)_day22总结
    思想:java中,父类的方法中传入的形参的数据类型是泛型,子类的方法的形参想只要一种确定的数据类型,子类该如何做呢?
    几种后端开发技术的选型调研
  • 原文地址:https://www.cnblogs.com/95lyj/p/8945183.html
Copyright © 2011-2022 走看看