Python的queue模块的大致使用(细致解释,适合小白)

此文的前提是你会使用threading库,如果还不会使用,可以参考我之前写的threading库文章

Python的threading库的大致使用(细致解释,适合小白)

正文

queue模块通常与多线程,也就是threading库一起使用。

其作用是在多线程或多进程环境中安全地传递数据,或者说是一种常见的同步机制。

可以想象一下,此时有一个仓库,里面存放了十件货物,两位工人要将他们取出。对于人来说,会很自然的选择两人各自搬一件货物以此达到最大效率。但解释器不会这么做,他们不会自己进行工作排序,所以他们很可能会同时对一件货物进行搬送。

那么此时,我们就要告诉解释器该如何去把这十件货物最有效的搬送(执行)

此时我们就要用到queue模块。

下面对queue模块常用方法和概念进行介绍。

一:queue类的主要方法:

1:

        put(item[,block[,timeout]]

put(item[, block[, timeout]])
# 将项目放入队列。如果队列已满且block为True(默认为True)——
#——则阻塞直到有空间可用或超时;如果block为False,则引发queue.Full异常。
# 其中,item: 这是必需的参数,表示要放入队列的项目
# block (可选): 这是一个可选的参数,如果指定为 True(默认值),则在队列已满的情况下,put 操作会阻塞,直到队列有空间可用。如果指定为 False,则在队列已满时会立即引发 queue.Full 异常。
# timeout (可选): 这是另一个可选参数,表示在阻塞模式下的超时时间,以秒为单位。如果队列已满并且 block 是 True,则最多等待 timeout 秒,如果在这个时间内队列有空间就放入项目;如果超时仍然没有空间,就引发 queue.Full 异常。如果没有指定 timeout,则会一直等待,直到队列有空间。

         所以,put(item[, block[, timeout]])的调用方式可以有三种。

put(item)
# 使用默认值,即阻塞等待队列有空间。

 

put(item, block=False)
# 立即尝试放入,如果队列已满就引发异常

 

put(item, block=True, timeout=X)
# 阻塞等待队列有空间,最多等待 X 秒

 2:

        get([block[,timeout]])

get([block[, timeout]])
# 从队列中获取并移除一个项目。如果队列为空且block为True(默认为True)——
# ——则阻塞直到有项目可用或超时;如果block为False,则引发queue.Empty异常
# get(): 这是必需的参数,表示从队列中获取并移除一个项目。
# block (可选): 这是一个可选的参数。如果指定为 True(默认值),在队列为空的情况下,get 操作会阻塞,直到队列有项目可取。如果指定为 False,在队列为空时会立即引发 queue.Empty 异常
# timeout (可选): 这是另一个可选参数,表示在阻塞模式下的超时时间,以秒为单位。如果队列为空且 block 是 True,则最多等待 timeout 秒,如果在这个时间内队列有项目就获取;如果超时仍然没有项目,就引发 queue.Empty 异常。如果没有指定 timeout,则会一直等待,直到队列有项目。

         同理,get([block[,timeout]]) 也有三种调用方式

get()
# 使用默认值,即阻塞等待队列有项目可取。

 

get(block=False)
# 立即尝试获取项目,如果队列为空就引发异常。
get(block=True, timeout=X)
# 阻塞等待队列有项目可取,最多等待 X 秒。

 

 3:

        qsize()

qsize()
# 返回队列中当前的项目数量

 4:

        empty()

empty()
# 如果队列为空,返回True;否则返回False

 5:

        full()

full()
# 如果队列已满,返回True;否则返回False

二:阻塞和非阻塞的介绍:

        在使用put和get方法适合,可以通过block和timeout参数来控制阻塞行为。

        如果block为T,也就是默认情况下,并且timeout为正值,则会最多等待timeout秒

        如果timeout为负值则会一直等待下去,直到有项目或者空间可用

        如果block设置为F,也就是False,那么将会立即引发queue.Full或者queue.Empty异常

三:特殊值

我们可以使用一些特殊的值,比如说:none来进行一些通知之类的操作

示例:

# 如果队列中获取到的项目名称是None,那么说明队列中已经没有任务需要处理了
# 那么就会执行break结束改线程的执行
if item is None:
   break

......

# 向队列中加入一个特殊的值,用于通知某个线程退出
my_queue.put(None)

那么现在,根据我们所学,写一个能解决我们一开始提到的问题的脚本。

import queue
import threading
import time    #模拟时间

# 定义工人(线程)的工作函数,或者说定义线程的执行逻辑
def worker(task_queue):
    while True:
        # 从任务队列中取出一个任务
        task = task_queue.get()

        # 如果取到的任务是None,表示任务结束,线程退出循环
        if task is None:
            break

        # 模拟任务的执行时间
        print(f"Worker is processing task for {task} seconds")
        time.sleep(task)

if __name__ == "__main__":
    # 创建一个任务队列
    task_queue = queue.Queue()

    # 添加任务到队列
    tasks = [3, 1, 4, 1, 5, 9, 2, 6,5,3]
    for task in tasks:
        task_queue.put(task)

    # 创建两个工人(线程)来执行任务
    worker1 = threading.Thread(target=worker, args=(task_queue,))
    worker2 = threading.Thread(target=worker, args=(task_queue,))

    # 启动工人(线程)
    worker1.start()
    worker2.start()

    # 等待所有任务完成
    worker1.join()
    worker2.join()

小结:通过queue模块,我们能更准确的告诉python解释器我们需要的执行逻辑与顺序,以此更为精确的达到我们的目的。

ps:上述脚本是个非常非常简单的示例脚本,而在实际使用中,queue模块会起到更大的作用,同时情景也会更加复杂,但总的来说,queue模块的使用并不难,只需要梳理好逻辑,然后准确的向python表达出来就好。

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值