python 之队列和生产者消费者模型、基于selectors模块实现的IO多路复用

创建一个“队列”对象
import Queue
q = Queue.Queue(maxsize = 10)


Queue.Queue类即是一个队列的同步实现。队列长度可为无限或者有限。
可通过Queue的构造函数的可选参maxsize来设定队列长度。
如果maxsize小于1就表示队列长度无限。

q.put(10)
将一个值放入队列中
调用队列对象的put()方法在队尾插入一个项目。
put()有两个参数,第一个item为必需的,为插入项目的值;第二个block为可选参数,默认为1。
如果队列当前为空且block为1,put()方法就使调用线程暂停,直到空出一个数据单元。
如果block为0,put方法将引发Full异常。


q.get()
将一个值从队列中取出
调用队列对象的get()方法从队头删除并返回一个项目。可选参数为block,默认为True。
如果队列为空且block为True,get()就使调用线程暂停,直至有项目可用。
如果队列为空且block为False,队列将引发Empty异常。

q.join()和q.task_done()搭配使用,

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


import
queue q = queue.Queue(5) q.put(10) q.put(20) print(q.get()) #10 q.task_done() print(q.get()) #20 q.task_done() q.join() print("ending!")

 

其他常用方法:
'''

此包中的常用方法(q = Queue.Queue()):

q.qsize() 返回队列的大小
q.empty() 如果队列为空,返回True,反之False
q.full() 如果队列满了,返回True,反之False
q.full 与 maxsize 大小对应
q.get([block[, timeout]]) 获取队列,timeout等待时间
q.get_nowait() 相当q.get(False)非阻塞 
q.put(item) 写入队列,timeout等待时间
q.put_nowait(item) 相当q.put(item, False)
q.task_done() 在完成一项工作之后,q.task_done() 函数向任务已经完成的队列发送一个信号
q.join() 实际上意味着等到队列为空,再执行别的操作

'''

 

队列的先进先出模式:

import queue


#q=queue.Queue(3)  # 默认是先进先出(FIFO)


# q.put(111)
# q.put("hello")
# q.put(222)

# q.put(223,False)
#
# print(q.get())
# # print(q.get())
# # print(q.get())
# #
# q.get(False)

 

队列的先进后出模式:

#  先进后出模式
# q=queue.LifoQueue()  #  Lifo  last in first out
# 
# 
# q.put(111)
# q.put(222)
# q.put(333)
# 
# print(q.get())
# print(q.get())
# print(q.get())

 

队列的优先级:

# 优先级

q=queue.PriorityQueue()

q.put([4,"hello4"])
q.put([1,"hello"])
q.put([2,"hello2"])

print(q.get())
print(q.get())

 

生产者消费模型:

#生产者消费者模型

import time,random
import queue,threading

q = queue.Queue()

def Producer(name):
  count = 0
  while count <10:
    print("making........")
    time.sleep(2)
    q.put(count)
    print('Producer %s has produced %s baozi..' %(name, count))

    count +=1
    #q.task_done()
    #q.join()
    print("ok......")

def Consumer(name):
  count = 0
  while count <10:
    time.sleep(1)
    if not q.empty():
        data = q.get()
        #q.task_done()
        #q.join()
        print(data)
        print('\033[32;1mConsumer %s has eat %s baozi...\033[0m' %(name, data))
    else:
        print("-----no baozi anymore----")

    count +=1

p1 = threading.Thread(target=Producer, args=('A',))
c1 = threading.Thread(target=Consumer, args=('B',))

# c2 = threading.Thread(target=Consumer, args=('C',))
# c3 = threading.Thread(target=Consumer, args=('D',))
p1.start()
c1.start()
# c2.start()
# c3.start()


#

 

selectors 模块:

import selectors  # 基于selectors模块实现的IO多路复用,建议大家使用

import socket

sock=socket.socket()
sock.bind(("127.0.0.1",8800))

sock.listen(5)

sock.setblocking(False)

sel=selectors.DefaultSelector() #根据具体平台选择最佳IO多路机制,比如在linux,选择epoll

def read(conn,mask):

    try:
        data=conn.recv(1024)
        print(data.decode("UTF8"))
        data2=input(">>>")
        conn.send(data2.encode("utf8"))
    except Exception:
        sel.unregister(conn)

def accept(sock,mask):

    conn, addr = sock.accept()
    print("conn",conn)
    sel.register(conn,selectors.EVENT_READ,read)

sel.register(sock,selectors.EVENT_READ,accept)  # 注册事件

while 1:

    print("wating...")
    events=sel.select()   #  监听    [(key1,mask1),(key2,mask2)]
    for key,mask in events:

        # print(key.fileobj)    # conn
        # print(key.data)       # read
        func=key.data
        obj=key.fileobj

        func(obj,mask)  # 1 accept(sock,mask)    # 2 read(conn,mask)

 

posted @ 2017-05-11 16:15  Adamanter  阅读(201)  评论(0编辑  收藏  举报