加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

生产者、消费者模型---Queue类

发布时间:2020-12-17 00:16:11 所属栏目:Python 来源:网络整理
导读:Queue队列在几乎每种编程语言都会有,python的列表隐藏的一个特点就是一个后进先出(LIFO)队列。而本文所讨论的Queue是python标准库queue中的一个类。它的原理与列表相似,但是先进先出(FIFO)队列。而内部实现更为完善,有很好的数据保护机制和较高的稳定

Queue队列在几乎每种编程语言都会有,python的列表隐藏的一个特点就是一个后进先出(LIFO)队列。而本文所讨论的Queue是python标准库queue中的一个类。它的原理与列表相似,但是先进先出(FIFO)队列。而内部实现更为完善,有很好的数据保护机制和较高的稳定性。

Queue队列在编程中的实际应用:进程中的通信

?????? 假如两个进程需要互通数据,怎么做?用全局变量,然后在进程中通过global关键字引入全局变量?那么问题是,怎么控制时间效应问题,即什么时候获取、传送变量?如何保证数据的安全性?显然这种方案不是很恰当。python为实现进程的通信提出了几种机制,本文的Queue就是其中一种。另外还有Value,Pipe,Signal等。

关于Signal可以看看我之前写的文章:

首先需要介绍Queue的类方法:

1. put() ?????????将元素塞进队列,当队列满时不阻塞等待

2. put_nowait()??? 将元素塞进队列,当队列满时阻塞等待

3. get()???????? ??从队列中取出元素,如果队列为空,阻塞等待

4.get_nowait()???? 从队列中取出元素,如果队列为空,不阻塞等待

5. full()?????????? 判断队列是否为已经满

6. empty()??????? 判断队列是否为空

7. qsize()???????? 获取队列的元素个数

8. task_done() ????当队列中的任务完成之后会自动调用task_done通知Queue,并对join()方法其作用

9. join()?? ???????阻塞等待直到所有的队列任务完成(被取出)

几个关键方法的详细解析

1. put(item,block = True,timeout = None)

将数据放进队列,item为需要塞进的元素,可以是基本数据类型变量,也可以是函数。block默认为True,即当Queue已经满时,阻塞等待(阻塞是同步的,会影响下面的程序运行)。timeout为阻塞等待超时时间,单位为秒,当超过指定时间,退出阻塞,同时报出Queue.Full错误。

2. put_nowait(item)

基本用法与put相同。当队列为满时,不阻塞等待,相当于put(item,block = False)

3. get(block= True,timeout = None)

??? 获取队列元素,block默认为True,当队列为空时,阻塞等待。timeout为超时时间,单位为秒,当超过指定时间,退出等待。

一、Queue类方法基本使用(为了方便调用接口,在Queue基础上再进行了一次封装):

queue <span style="color: #0000ff">class MyQueue(): <span style="color: #008000">#<span style="color: #008000">自定义一个MyQueue类
<span style="color: #0000ff">def <span style="color: #800080">init(self,size=3<span style="color: #000000">):
self.max_size =<span style="color: #000000"> size
self.queue =<span style="color: #000000"> Queue(size)

<span style="color: #008000">#<span style="color: #008000">put()方法可以传入数值
<span style="color: #008000">#<span style="color: #008000"> item1 = 2
<span style="color: #008000">#<span style="color: #008000"> item2 = 3
<span style="color: #008000">#<span style="color: #008000"> item3 = 3
<span style="color: #008000">#<span style="color: #008000"> queue.put(item1)
<span style="color: #008000">#<span style="color: #008000"> queue.put(item2)
<span style="color: #008000">#<span style="color: #008000"> queue.put(item3)

<span style="color: #008000"&gt;#</span><span style="color: #008000"&gt; 超过长度的内容</span>
<span style="color: #008000"&gt;#</span><span style="color: #008000"&gt; item4 = 5</span>
<span style="color: #008000"&gt;#</span><span style="color: #008000"&gt; queue.put_nowait(item4)</span>

<span style="color: #008000">#<span style="color: #008000">put()方法也可以传入函数
<span style="color: #0000ff">def<span style="color: #000000"> _print_num(self,n):
num =<span style="color: #000000"> n
<span style="color: #0000ff">return<span style="color: #000000"> num

</span><span style="color: #0000ff"&gt;def</span><span style="color: #000000"&gt; write_queue(self):
    </span><span style="color: #0000ff"&gt;for</span> n <span style="color: #0000ff"&gt;in</span> range(4<span style="color: #000000"&gt;):
        </span><span style="color: #0000ff"&gt;try</span><span style="color: #000000"&gt;:
          self.queue.put_nowait(self._print_num(n))  </span><span style="color: #008000"&gt;#</span><span style="color: #008000"&gt;如果队列已经满了,会报出Full错误</span>
        <span style="color: #0000ff"&gt;except</span><span style="color: #000000"&gt;:
            </span><span style="color: #0000ff"&gt;print</span>(<span style="color: #800000"&gt;'</span><span style="color: #800000"&gt;队列已经满了,无法添加内容</span><span style="color: #800000"&gt;'</span><span style="color: #000000"&gt;)


</span><span style="color: #0000ff"&gt;def</span><span style="color: #000000"&gt; print_queue_length(self):
   </span><span style="color: #0000ff"&gt;print</span>(<span style="color: #800000"&gt;'</span><span style="color: #800000"&gt;队列的长度是:</span><span style="color: #800000"&gt;'</span><span style="color: #000000"&gt;,self.queue.qsize())

</span><span style="color: #0000ff"&gt;def</span><span style="color: #000000"&gt; get_queue(self):
    </span><span style="color: #0000ff"&gt;if</span> self.queue.empty() <span style="color: #0000ff"&gt;is</span><span style="color: #000000"&gt; False:
        queue_size </span>=<span style="color: #000000"&gt; self.queue.qsize()
        n </span>= 1
        <span style="color: #0000ff"&gt;for</span> i <span style="color: #0000ff"&gt;in</span><span style="color: #000000"&gt; range(queue_size):
            </span><span style="color: #0000ff"&gt;if</span> n ><span style="color: #000000"&gt; queue_size:
                </span><span style="color: #0000ff"&gt;print</span>(<span style="color: #800000"&gt;'</span><span style="color: #800000"&gt;队列已经空了</span><span style="color: #800000"&gt;'</span><span style="color: #000000"&gt;)
            value </span>=<span style="color: #000000"&gt; self.queue.get()
            </span><span style="color: #0000ff"&gt;print</span>(<span style="color: #800000"&gt;'</span><span style="color: #800000"&gt;队列第%s个值是:%s</span><span style="color: #800000"&gt;'</span>%<span style="color: #000000"&gt;(n,value))
            n </span>+= 1
    <span style="color: #0000ff"&gt;else</span><span style="color: #000000"&gt;:
      </span><span style="color: #0000ff"&gt;print</span>(<span style="color: #800000"&gt;'</span><span style="color: #800000"&gt;队列已经空了</span><span style="color: #800000"&gt;'</span><span style="color: #000000"&gt;)

<span style="color: #008000">#<span style="color: #008000">实例化代码
myqueue =<span style="color: #000000"> MyQueue()
myqueue.write_queue()
myqueue.print_queue_length()
myqueue.get_queue()

运行结果

二、多进程间通信:

multiprocessing <span style="color: #008000">#<span style="color: #008000">将数据装进队列
<span style="color: #0000ff">def<span style="color: #000000"> put_msg(q,lock):
lock.acquire()
<span style="color: #0000ff">for i <span style="color: #0000ff">in range(3<span style="color: #000000">):
<span style="color: #0000ff">print(<span style="color: #800000">'<span style="color: #800000">Put the %s into the queue<span style="color: #800000">'%<span style="color: #000000">i)
q.put(i)
lock.release()

<span style="color: #008000">#<span style="color: #008000">将数据取出
<span style="color: #0000ff">def<span style="color: #000000"> get_msg(q):
<span style="color: #0000ff">while<span style="color: #000000"> True:
<span style="color: #0000ff">if <span style="color: #0000ff">not<span style="color: #000000"> q.empty():
value =<span style="color: #000000"> q.get(False)
<span style="color: #0000ff">print(<span style="color: #800000">'<span style="color: #800000">Get the %s from the queue<span style="color: #800000">'%<span style="color: #000000">value)
<span style="color: #0000ff">else<span style="color: #000000">:
<span style="color: #0000ff">break

<span style="color: #0000ff">if <span style="color: #800080">name == <span style="color: #800000">'<span style="color: #800000">main<span style="color: #800000">'<span style="color: #000000">:
manager =<span style="color: #000000"> Manager()
q = manager.Queue(5) <span style="color: #008000">#<span style="color: #008000">队列长度设为5
lock =<span style="color: #000000"> manager.Lock()
processes =<span style="color: #000000"> []
process1 = Process(target=put_msg,args=<span style="color: #000000">(q,lock))
process2 = Process(target=get_msg,))

processes.append(process1)
processes.append(process2)
</span><span style="color: #0000ff"&gt;for</span> p <span style="color: #0000ff"&gt;in</span><span style="color: #000000"&gt; processes:
    p.start()
    p.join()</span></pre>

在父进程中创建Queue,传入两个子进程,因为python中父进程无法与子进程进行通信,必须使用Manage来实现。为了只有一个进程在对Queue进行操作,使用Manage的Lock。

<div class="cnblogs_code">

121 2  the queue

解析:

操作系统中的进程本质上是一个程序在一个数据集上动态执行的过。而进程通常是由程序、数据集和进程控制块组成。

程序:也就是我们平时在IDE上编写的代码,描述了一个进程的内部运行逻辑和功能;

数据集:程序执行过程中需要使用到的资源,包括IO资源和基本数据;

进程控制块:操作系统通过进程控制块来对进程进行控制和管理,记录进程的外部特征和描述进程的执行过程

为了确保进程的独立性和安全性,操作系统在执行程序的时候会用到一种数据解构--栈。程序和数据的入栈和出栈对应进程的等待执行和正式执行。如此一来,各进程间的数据集是相互隔离的(即使可能在同一个栈中)。要进行进程间的通信或者子进程和父进程间的通信,就必须通过一定的机制。上面谈到到的Queue和Manage正是python中实现进程间通信的其中两种。

参考文章:

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读