python基础学习日志day9--线程队列queue

一:线程queu作用

  Python中,queue是线程间最常用的交换数据的形式。

  队列两个作用:一个是解耦,一个是提高效率

二:语法

  1)队列的类

  class queue.Queue(maxsize=0) #先入先出
  class queue.LifoQueue(maxsize=0) #last in fisrt out 
  class queue.PriorityQueue(maxsize=0) #存储数据时可设置优先级的队列

  优先级队列的构造函数。maxsize可以放置在队列中的项的最大个数。

  一旦达到这个大小,插入将阻塞,直到队列项被消耗。maxsize值为小于等于0,表示队列的大小是无限的。

  2)队列两个异常

  exception queue.Empty 当调一个队列是空的,时候调用get()或者get_nowait()会抛出阻塞

  exception queue.Full 当调一个队列是最大值,时候调用put()或者put_nowait()会抛出非阻塞

  3)队列的方法

  Queue.qsize() 判断队列大小
  Queue.empty() #空返回真
  Queue.full() # 满反回真
  Queue.put(item, block=True, timeout=None)
  #给队列增加一个item。如果设置了block为true,并且timeout=None,表示一直阻塞,直到队列可以放item进去。
  如果设置了timeout=为正值,表示最多阻塞多少秒,还是不能把item放进去,就会抛出queue.Full异常。
  如果block为False,item不能放进去就抛出queue.Full。
  Queue.put_nowait(item) == Queue.put(item, block=False)
  Queue.get(block=Truetimeout=None)
  #从队列中删除并返回一个item。如果设置了block为true,并且timeout=None,表示一直阻塞,直到队列可以取item。  
  如果设置了timeout=为正值,表示最多阻塞多少秒,还是不能取到item,就会抛出queue.Empty异常。  
  如果block为False,不能取到item就抛出queue.Empty 

   Queue.get_nowait() ==Queue.get(False)

  Queue.task_done()

  Queue.task_done(),每次从queue中get一个数据之后,当处理好相关问题,最后调用该方法,以提示q.join()是否停止阻塞,让线程向前执行或者退出;

  Queue.join(),阻塞,直到queue中的数据均被删除或者处理。为队列中的每一项都调用一次。

  对于生产者-消费者模型,这样做还是有问题的,因为如果queue初始为空,q.join()会直接停止阻塞,继而执行后续语句;

  如果有多个消费者,没有生产者,且queue始初化为一定的数据量,则可以正常执行。

三:生产者消费者模型

  在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。

  为什么要使用生产者和消费者模式

  在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。

  什么是生产者消费者模式

  生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。

四:代码

 

# -*- coding:utf-8 -*-
__author__ = ‘shisanjun‘

import queue
import time
import threading

q=queue.Queue()

def producer(name):

    for i in range(10):
        print("%s 生产了包子%s..." %(name,i))
        q.put(i) #给队列增加一个item
        time.sleep(1)
    q.join()#阻塞,直到queue中的数据均被删除或者处理
    print("包子都吃完了")

def consumer(name):

    while True:
        if q.qsize()>0:
            print("%s 吃了包子%s....." %(name,q.get()))
            q.task_done() ##告知这个任务执行完了
        time.sleep(1)

p=threading.Thread(target=producer,args=("qjj",))
c=threading.Thread(target=consumer,args=("lsj",))
p.start()
c.start()

"""
qjj 生产了包子0...
lsj 吃了包子0.....
qjj 生产了包子1...
lsj 吃了包子1.....
qjj 生产了包子2...
qjj 生产了包子3...
lsj 吃了包子2.....
qjj 生产了包子4...
lsj 吃了包子3.....
lsj 吃了包子4.....
qjj 生产了包子5...
lsj 吃了包子5.....
qjj 生产了包子6...
qjj 生产了包子7...
lsj 吃了包子6.....
qjj 生产了包子8...
lsj 吃了包子7.....
lsj 吃了包子8.....
qjj 生产了包子9...
lsj 吃了包子9.....
包子都吃完了
"""
时间: 2024-08-28 12:08:51

python基础学习日志day9--线程队列queue的相关文章

python基础学习日志day5-各模块文章导航

python基础学习日志day5---模块使用 http://www.cnblogs.com/lixiang1013/p/6832475.html python基础学习日志day5---time和datetime模块 http://www.cnblogs.com/lixiang1013/p/6848245.html python基础学习日志day5---random模块http://www.cnblogs.com/lixiang1013/p/6849162.html python基础学习日志da

python基础学习日志day10-进程间数据通信

一:进程间数据交换方法 不同进程间内存是不共享的,要想实现两个进程间的数据交换,可以用以下方法: 1)Queue,使用方法跟threading里的queue差不多 # -*- coding:utf-8 -*- __author__ = 'shisanjun' from multiprocessing import Process,Queue import threading import queue # def run(q): # q.put([42,None,"hello"]) #

python基础学习日志day5---logging模块

很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误.警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储各种格式的日志,logging的日志可以分为 debug(), info(), warning(), error() and critical() 5个级别,下面我们看一下怎么用. 最简单用法 1 2 3 4 5 6 7 8 import logging logging.warning("user [alex] attempt

python基础学习日志day8-SocketServer

摘要: SocketServer简化了网络服务器的编写.它有4个类:TCPServer,UDPServer,UnixStreamServer,UnixDatagramServer.这4个类是同步进行处理的,另外通过ForkingMixIn和ThreadingMixIn类来支持异步. 创建服务器的步骤.首先,你必须创建一个请求处理类,它是BaseRequestHandler的子类并重载其handle()方法.其次,你必须实例化一个服务器类,传入服务器的地址和请求处理程序类.最后,调用handle_

python基础学习日志day9--线程event

一:线程event作用 Python提供了Event对象用于线程间通信,它是线程设置的信号标志,如果信号标志位真,则其他线程等待直到信号结束. Event对象实现了简单的线程通信机制,它提供了设置信号,清楚信号,等待等用于实现线程间的通信. 官方解释 event是一个简单的同步对象:event表示内部标志和线程.可以等待标志设置,或设置或清除标志本身. 二:event使用 1)event = threading.Event() 申明event实例 2)event.wait().线程设置等待标志

python基础学习日志day10-事件驱动模型

论事件驱动与异步IO 原文:http://www.cnblogs.com/alex3714/articles/5248247.html常,我们写服务器处理模型的程序时,有以下几种模型: (1)每收到一个请求,创建一个新的进程,来处理该请求: (2)每收到一个请求,创建一个新的线程,来处理该请求: (3)每收到一个请求,放入一个事件列表,让主进程通过非阻塞I/O方式来处理请求 上面的几种方式,各有千秋, 第(1)中方法,由于创建新的进程的开销比较大,所以,会导致服务器性能比较差,但实现比较简单.

操作 python基础学习日志day8-socketserver

一:socketserver简化了网络服务器的编写. 它有4个类:TCPServer,UDPServer,UnixStreamServer,UnixDatagramServer. 这4个类是同步进行处理的,另外通过ForkingMixIn和ThreadingMixIn类来支持异步 class socketserver.TCPServer(server_address, RequestHandlerClass, bind_and_activate=True) class socketserver.

python基础学习日志day8-socket

一:什么是socket socket通常也称为作为"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"给网络发送请求或者应答网络请求. socket起源于Unix,而Unix/Linux基本哲学之一就是"一切皆文件",对于文件用[打开][读写][关闭]模式来操作.socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO.打开.关闭) socket和file的

python基础学习日志day8-异常处理

一.异常基础 在编程过程中为了增加友好性,在程序出现bug时一般不会将错误信息显示给用户,而是现实一个提示的页面. 1)常用方式: try: pass except Exception as e: pass 一直尝试try中的代码,如果遇到错误和except中异常相同,就执行except中代码,如果和except没有相同,还是会抛出异常 # -*- coding:utf-8 -*- __author__ = 'shisanjun' names=['1','2','3'] data={} try: