进程锁-生产者消费者模型

进程锁

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

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

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

# 模拟抢票功能
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)
原文地址:https://www.cnblogs.com/sandy-123/p/10453034.html