python中的队列

  1. 先说一下队列的导入问题,在python2中的导入为:from Queue import Queue 在python3中的导入为:from queue import Queue,不然就会报错
  2. Python的Queue模块中提供了同步的、线程安全的队列类,包括FIFO(先入先出)队列Queue,LIFO(后入先出)队列LifoQueue,和优先级队列PriorityQueue。这些队列都实现了锁原语,能够在多线程中直接使用,可以使用队列来实现线程间的同步。那为什么说线程是安全的,因为python的多线程其实是骗人的,因为全局解释器锁(GIL)。
  3. 队列的一些常用命令:
Queue.queue 队列数据
Queue.qsize() 返回队列的大小
Queue.empty() 如果队列为空,返回True,反之False
Queue.full() 如果队列满了,返回True,反之False,Queue.full 与 maxsize 大小对应
Queue.get(timeout=10)获取队列,timeout等待时间 注意 timeout参数可以不写,当不写的时候,当队列取光之后再执行get将会一直堵塞在那里,当有timeout参数时,到底时间之后没有值将会报错,我们需要异常处理,或者使用empty()来提前判断做对应的处理
Queue.get_nowait() 相当于Queue.get(False),非阻塞方法
Queue.put(item) 写入队列(堵塞) 注意,如果队列已满,再放入数据,则会一直堵塞在那里,所以可以用full()提前做判断来做对应的操作
Queue.put_nowait(item) 写入队列(非堵塞) 注意,如果队列已满,再放入数据,则会会报错,我们只需异常处理即可
Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号。每个get()调用得到一个任务,接下来task_done()调用告诉队列该任务已经处理完毕。
Queue.join() 如果接收不到task_done()的信号,那么join()就一直堵塞在那里,简单来说task_done()需要和join配合
  1. 代码示例:
from queue import Queue, LifoQueue, PriorityQueue

# 先进先出队列
q = Queue(maxsize=5)
# 后进先出队列
lq = LifoQueue(maxsize=6)
# 优先级队列
pq = PriorityQueue(maxsize=5)

for i in range(5):
    q.put(i)
    lq.put(i)
    pq.put(i)

print(q.get())
print(lq.get())
print(pq.get())
print(q.get())
print(lq.get())
print(pq.get())

结果:

0
4
0
1
3
1
  1. put()与put_nowait()的区别:堵塞与非堵塞
from queue import Queue, LifoQueue, PriorityQueue

# 先进先出队列
q = Queue(maxsize=2)

try:
    for i in range(5):
        # q.put(i)  满了就一直堵塞
        print(i)
        q.put_nowait(i)
except:
    print('满了')

print(q.get())

执行结果:

0
1
2
满了
0

  1. get()与get_nowait()的区别
from queue import Queue, LifoQueue, PriorityQueue

# 先进先出队列
q = Queue(maxsize=2)


for i in range(2):
    q.put(i)



print(q.get())
print(q.get())
# print(q.get()) 将一直堵塞
print(q.get_nowait())  # 相当于q.get(timeout=5) 区别就是q.get_nowait()立即报错 q.get(timeout=5)等待5秒后报错
print('结束')
  1. join()和task_done()的关系
from queue import Queue, LifoQueue, PriorityQueue
import time


q = Queue()

def run():
    msg = q.get()
    print(msg)
    time.sleep(1)
    q.task_done()
    print('0000000')

    msg = q.get()
    print(msg)
    time.sleep(1)
    q.task_done()  # q.task_done()就是用来告诉join队列是否为空(任务结束),结束则不堵塞
    print('0000001111')



for i in range(2):
    q.put(i)

run()
q.join()
print('结束了')

不注释第二个q.task_done()的执行结果:

0
0000000
1
0000001111
结束了

注释掉第二个q.task_done()的执行结果:

0
0000000
1
0000001111
......一直堵塞中
  1. 双边队列deque
from queue import Queue, LifoQueue, PriorityQueue, deque

dq=deque([-1, 0, 1, 2])
dq.append(3)  # 双边队列添加数值(默认从右边添加)
print(dq)  # 结果:deque([-1, 0, 1, 2, 3])

dq.pop() # 删除数据(默认删除1 从右面删除)
print(dq)  # 结果 deque([-1, 0, 1, 2])

dq.popleft() # 从左边删除
print(dq)  # 结果:deque([0, 1, 2])

dq.appendleft(-1) # 从左边添加
print(dq) # 结果:deque([-1, 0, 1, 2])

print(len(dq)) # 查看长度 结果:4
  1. 多线程配合队列
from queue import Queue, LifoQueue, PriorityQueue, deque
import time, threading

q = Queue(maxsize=0)

def product(name):
    count = 1
    while True:
        q.put('气球兵{}'.format(count))
        print('{}训练气球兵{}只'.format(name, count))
        count += 1
        time.sleep(5)


def consume(name):
    while True:
        print('{}使用了{}'.format(name, q.get()))
        time.sleep(1)
        q.task_done()


t1 = threading.Thread(target=product, args=('wpp',))
t2 = threading.Thread(target=consume, args=('ypp',))
t3 = threading.Thread(target=consume, args=('others',))

t1.start()
t2.start()
t3.start()
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值