zoukankan      html  css  js  c++  java
  • 进程锁-生产者消费者模型

    进程锁

    进程中的数据安全问题:当多个进程同时去访问同一段数据的时候,就容易产生数据的不安全

    给代码上锁,实际上是对这一段代码有一个串行的要求,所有的异步在锁内都变成了同步的,同时大大降低了代码的效率

    但是在数据安全面前,所有的效率问题都不重要

    # 模拟抢票功能
    import json
    import time
    from multiprocessing import Process,Lock
    
    def search_ticket(name):
        '''
        查票功能
        :param name: 进程对象
        :return:
        '''
        with open('ticket')as f:
            ticket_dic = json.load(f)
        time.sleep(0.1)
        print('%s : 当前余票%s张'%(name,ticket_dic['count']))
    
    def buy_ticket(name):
        '''
        买票功能
        :param name: 进程对象
        :return:
        '''
        with open('ticket')as f:
            ticket_dic = json.load(f)
        time.sleep(0.1)
        if ticket_dic['count'] > 0:
            print('%s查询余票%s张'%(name,ticket_dic['count']))
            ticket_dic['count'] -= 1
            print('%s购票成功'%name)
        time.sleep(0.1)
        with open('ticket','w')as f:
            json.dump(ticket_dic,f)
    
    # def use_system(name,lock):
    #     search_ticket(name)
    #     lock.acquire()         #上锁
    #     buy_ticket(name)
    #     lock.release()         #解锁
    
    def use_system(name,lock):
        '''
        进程锁
        :param name: 进程对象
        :param lock: 进程锁
        :return:
        '''
        search_ticket(name)
        with lock:             # 使用上下文管理会更好
            buy_ticket(name)
    
    if __name__ == '__main__':
        lock = Lock()          #进程锁
        for i in range(10):   #创建10个进程对象
            p = Process(target=use_system,args=('alex'+str(i),lock))
            p.start()

    进程通信   IPC

    队列  自带进程锁

    特点:先进先出  进程之间数据安全

    队列的底层: 管道Pipe   没有锁,数据不安全   

    管道的底层: 依赖于socket通信

    所有进程之间的通信都是依赖socket进行的

    socket 基于文件地址家族的通信

    p = queue()  创建队列
    q.put('a')   往对列里放内容'a'
    q.get()      从队列中取值
    q.empty()    判断队列是否为空
    q.full()     判断队列是否为满
    q.qsize()    队列中数据的个数
    
    # 需要注意的是,因为系统反应时间差的原因,在多进程中判断空,判断满,判断个数的方法都不准确
    from multiprocessing import Queue
    q = Queue(5)      # 规定队列中只允许放5个数据
    q.put(1)
    q.put(2)
    q.put(3)
    q.put(4)
    q.put(5)
    print('111')     #会打印
    q.put(6)         # 阻塞方法,当队列满员之后,会阻塞直到队列中空出一个位置为止
    print('222')    #将不会打印

    生产者消费者模型

    声称这和消费者彼此之间不直接通讯,而通过阻塞队列来进行通信,所有生产者生产完数据之后不用等待消费者处理,直接扔给阻塞对联,

    消费者不找生产者要数据,而是直接从阻塞队列里取

    阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力

    队列的get和put方法就是阻塞方法

    import time
    import random
    from multiprocessing import Process,Queue
    def consumer(q,name):
        while True:
            task = q.get()
            if task is None:break
            time.sleep(random.random())
            print('%s吃%s'%(name,task))
    
    def producer(q,n):
        for i in range(n):
            time.sleep(random.uniform(1,2))
            print('生产了泔水%s'%i)
            q.put('泔水%s'%i)
    
    if __name__ == '__main__':
        q = Queue()
        pro_l = []
        for i in range(5):
            p = Process(target=producer,args=(q,10))
            p.start()
            pro_l.append(p)
        p1 = Process(target=consumer,args=(q,'alex'))
        p2 = Process(target=consumer,args=(q,'wusir'))
        p1.start()
        p2.start()
        for p in pro_l:
            p.join()
        q.put(None)             #有几个消费者进程对象就需要有几个None
        q.put(None)
  • 相关阅读:
    非线性数据结构——树
    排序算法之插入排序
    web框架之environment处理
    web开发之http和wsgi
    python os模块和shutil模块
    python路径操作
    stringIO和bytesIO
    python文件操作
    设计模式
    设计模式
  • 原文地址:https://www.cnblogs.com/sandy-123/p/10453034.html
Copyright © 2011-2022 走看看