生产者消费者问题

多进程操作-进程锁multiprocess.Queue的使用

感情迁移 提交于 2019-11-29 19:38:41
一、ipc机制 进程通讯 管道:pipe 基于共享的内存空间 队列:pipe+锁 queue 下面拿代码来实现Queue如何使用: 案例一: from multiprocessing import Queue q = Queue() # 实例产生一个q队列 q.put('蔡徐坤') # 将括号内的数据加入队列中,先进先出 q.put([1,2,3]) q.put(3) print(q.get()) # 将队列里的数据取出来,先进先出 print(q.get()) print(q.get()) # q.put(5) print(q.get()) # 如果队列里面没有值,就会一直等待队0列有值。 案例二: from multiprocessing import Queue q = Queue(4) # 4 代表队列最大项数为4,不写则为无限制大小 q.put('蔡徐坤') # 将括号内的数据加入队列中,先进先出 q.put([1,2,3]) q.put(3) q.put(3) q.put(3) # 队列满了的话,会阻塞,等待q.get()放值后,才能加入队列 案例三:(从这往下都是了解) from multiprocessing import Queue q = Queue(3) q.put('zhao') q.put('zhao') q.put('zhao') q.put('zhao

并发编程之进程间通信

不羁岁月 提交于 2019-11-29 19:22:38
目录 并发编程之进程间通信 进程间通信--管道(multiprocessing.Pipe) 进程间通信--队列(multiprocessing.Queue) 队列的基础用法: 代码实例 生产者消费者模型 为什么要使用生产者和消费者模式 什么是生产者消费者模式 并发编程之进程间通信 进程间通信--管道(multiprocessing.Pipe) conn1,conn2 = Pipe() conn1.send('asfalfa') print(conn2.recv()) 双向通信, conn1 发送的内容会被 conn2 接收, from multiprocessing import Pipe,Process def func(conn1,conn2): conn2.close() while True: try: msg = conn1.recv() print(msg) except EOFError: conn1.close() break if __name__ == '__main__': conn1, conn2 = Pipe() p = Process(target=func,args=(conn1,conn2)) p.start() for i in range(10): conn2.send('shabi') conn2.close() 进程间通信--队列

进程间通信--Queue

℡╲_俬逩灬. 提交于 2019-11-29 19:22:09
进程间通信--Queue 一、进程间通信 进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的 二、队列 2.1 概念介绍 --multiprocessor.Queue 创建共享的进程队列,Queue是多进程安全的队列,可以使用Queue实现多进程之间的数据传递。 Queue([maxsize]) 创建共享的进程队列。 参数 :maxsize是队列中允许的最大项数。如果省略此参数,则无大小限制。 底层队列使用管道和锁定实现。 2.2 方法介绍 Queue([maxsize]): 创建共享的进程队列。maxsize是队列中允许的最大项数。如果省略此参数,则无大小限制。底层队列使用管道和锁定实现。另外,还需要运行支持线程以便队列中的数据传输到底层管道中。 Queue的实例q具有以下方法: q.get( [ block [ ,timeout ] ] )`:返回q中的一个项目。如果q为空,此方法将阻塞,直到队列中有项目可用为止。block用于控制阻塞行为,默认为True. 如果设置为False,将引发Queue.Empty异常(定义在Queue模块中)。timeout是可选超时时间,用在阻塞模式中。如果在制定的时间间隔内没有项目变为可用,将引发Queue.Empty异常。 q.get_nowait()

队列与生产者消费者模型

不想你离开。 提交于 2019-11-29 19:14:53
目录 一、队列 二、消费者生产者模型 什么是生产者消费者模式 为什么要使用生产者和消费者模式 基于队列(Queue)实现生产者消费者模型 生产者消费者模型总结 一、队列 ​ 进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的 创建队列的类(底层就是以管道和锁定的方式实现) : 1 Queue([maxsize]):创建共享的进程队列,Queue是多进程安全的队列,可以使用Queue实现多进程之间的数据传递。 **参数介绍:** 1 maxsize是队列中允许最大项数,省略则无大小限制。 方法介绍 1 q.put方法用以插入数据到队列中,put方法还有两个可选参数:blocked和timeout。如果blocked为True(默认值),并且timeout为正值,该方法会阻塞timeout指定的时间,直到该队列有剩余的空间。如果超时,会抛出Queue.Full异常。如果blocked为False,但该Queue已满,会立即抛出Queue.Full异常。 2 q.get方法可以从队列读取并且删除一个元素。同样,get方法有两个可选参数:blocked和timeout。如果blocked为True(默认值),并且timeout为正值,那么在等待时间内没有取到任何元素,会抛出Queue.Empty异常

堵塞队列-BlockingQueue

百般思念 提交于 2019-11-29 18:54:43
阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作是: 在队列为空时,获取元素的线程会等待队列变为非空。 当队列满时,存储元素的线程会等待队列可用。 阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。 BlockingQueue即阻塞队列,从 阻塞 这个词可以看出,在某些情况下对阻塞队列的访问可能会造成阻塞。被阻塞的情况主要有如下两种: 1. 当队列满了的时候进行入队列操作 2. 当队列空了的时候进行出队列操作 因此,当一个线程试图对一个已经满了的队列进行入队列操作时,它将会被阻塞,除非有另一个线程做了出队列操作;同样,当一个线程试图对一个空队列进行出队列操作时,它将会被阻塞,除非有另一个线程进行了入队列操作。 在Java中,BlockingQueue的接口位于java.util.concurrent 包中(在Java5版本开始提供),由上面介绍的阻塞队列的特性可知,阻塞队列是线程安全的。 在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题。通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利。本文详细介绍了BlockingQueue家庭中的所有成员

深入浅出计算机组成原理:理解Disruptor(下)-不需要换挡和踩刹⻋的CPU,有多快?(第55讲)

眉间皱痕 提交于 2019-11-29 17:31:08
一、引子 上一讲,我们学习了一个精妙的想法,Disruptor通过缓存行填充,来利用好CPU的高速缓存。不知道你做完课后思考题之后,有没有体会到高速缓存在实践中带来的速度提升呢? 不过,利用CPU高速缓存,只是Disruptor“快”的一个因素,那今天我们就来看一看Disruptor快的另一个因素,也就是“无锁”,而尽可能发挥CPU本身的高速处理性能。 二、缓慢的锁 Disruptor作为一个高性能的生产者-消费者队列系统,一个核心的设计就是通过RingBuffer实现一个无锁队列。 上一讲里我们讲过,Java里面的基础库里,就有像LinkedBlockingQueue这样的队列库。但是,这个队列库比起Disruptor利用的RingBuffer要慢上很多。慢的第益个原因我们说过, 因为链表的数据在内存里面的布局对于高速缓存并不友好,而RingBuffer所使用的数组则不然。 LinkedBlockingQueue慢,有另外一个重要的因素,那就是它对于锁的依赖。在生产者-消费者模式里,我们可能有多个消费者,同样也可能有多个生产者。多个生产者都要往队列的尾指针里面添加新的任务, 就会产生多个线程的竞争。于是,在做这个事情的时候,生产者就需要拿到对于队列尾部的锁。同样地,在多个消费者去消费队列头的时候,也就产生竞争。同样消费者也要拿到锁。 那只有意个生产者,或者一个消费者

生产者-消费者问题

烂漫一生 提交于 2019-11-29 16:28:12
目录 1. 概述 定义 缓冲区 2. 典型模型 模型一 模型二 可选需求 3. 数据结构队列C语言实现 4. 代码实现——互斥锁 + 条件变量 5. 代码实现——互斥锁 + Posix有名信号量 6. 代码实现——互斥锁 + Posix无名信号量 7. 效率对比 结论 奇怪的问题 1. 概述 定义 生产者消费者问题是线程同步的经典问题,也称为有界缓冲区问题,问题描述大致如下: 生产者和消费者之间共享一个有界数据缓冲区 一个或多个生产者(线程或进程)向缓冲区放置数据 一个或多个消费者(线程或进程)从缓冲区取出数据 缓冲区 生产者消费者问题中的缓冲区,包括队列缓冲区和环形缓冲区,它们都按照先进先出的顺序处理数据,我们现在只考虑队列缓冲区: 队列缓冲区通常使用普通的队列数据结构 队列内部实现可以是链表或数组 缓冲区有两个极端状态:缓冲区空,缓冲区满。链表队列和数组队列缓冲区空的含义相同,都是队列中没有一个元素的情形,但两者缓冲区满的含义不同: 数组队列在初始化时就必须指定最大容量,缓冲区满的条件很清晰 链表队列没有最大容量的概念,需要人为指定 此外,Posix消息队列也可以作为队列缓冲区,Posix当以无优先级消息的方式使用时,也是按照先进先出的顺序进行处理的。 本文只讨论第一种数据结构队列缓冲区,基于Posix消息队列缓冲区的生产者消费者问题,会在后续Posix消息队列中单独讲解。 2

生产者消费模型

六月ゝ 毕业季﹏ 提交于 2019-11-29 16:08:42
'''为什么要使用生产者消费者模型生产者指的是生产数据的任务,消费者指的是处理数据的任务,在并发编程中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。什么是生产者和消费者模式生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。这个阻塞队列就是用来给生产者和消费者解耦的'''from multiprocessing import Process, Queueimport timedef producer(q): for i in range(10): res = '包子%s'%i time.sleep(0.5) print('生产者生产了%s'%i) q.put(res)def consmer(q): while True: res = q.get() if res is None:break time.sleep(1) print('消费者吃了%s'%res)if __name

生产者消费者问题--BlockingQueue

巧了我就是萌 提交于 2019-11-29 10:14:12
# 代码: public class App { public static void main(String[] args) { BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(6); Producer producer = new Producer(queue); Consumer consumer = new Consumer(queue); producer.produce(5); consumer.consume(4); producer.produce(3); consumer.consume(2); } } class Producer { private BlockingQueue<Integer> queue; public Producer(BlockingQueue<Integer> queue) { this.queue = queue; } public void produce(final int val) { new Thread() { public void run() { try { int surplus = val; while (surplus > 0) { queue.put(1024); surplus--; System.out.printf("%s plan to

并发编程之多进程

旧时模样 提交于 2019-11-28 22:27:56
并发编程之:多进程 一 multiprocessing模块介绍 ​ python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程。Python提供了multiprocessing。 ​ multiprocessing模块用来开启子进程,并在子进程中执行我们定制的任务(比如函数),该模块与多线程模块threading的编程接口类似。   multiprocessing模块的功能众多:支持子进程、通信和共享数据、执行不同形式的同步,提供了Process、Queue、Pipe、Lock等组件。 ​ 需要再次强调的一点是:与线程不同,进程没有任何共享状态,进程修改的数据,改动仅限于该进程内。 二 Process类的介绍 ​ 创建进程的类 : Process([group [, target [, name [, args [, kwargs]]]]]),由该类实例化得到的对象,表示一个子进程中的任务(尚未启动) 强调: 1. 需要使用关键字的方式来指定参数 2. args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号 ​ 参数介绍: 1 group参数未使用,值始终为None 2 3 target表示调用对象,即子进程要执行的任务 4 5 args表示调用对象的位置参数元组