码迷,mamicode.com
首页 > 系统相关 > 详细

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

时间:2019-02-28 21:07:48      阅读:269      评论:0      收藏:0      [点我收藏+]

标签:get   位置   roc   地址   bsp   注意   异步   对象   socket通信   

进程锁

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

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

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

# 模拟抢票功能
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)

 

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

标签:get   位置   roc   地址   bsp   注意   异步   对象   socket通信   

原文地址:https://www.cnblogs.com/sandy-123/p/10453034.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!