python线程优先级队列知识点总结

Python线程优先级队列知识点总结

什么是线程优先级队列?

线程优先级队列是Python标准库中的一个模块,提供了一个可排序的、优先级队列的数据结构。

通常情况下,在多线程编程中,我们需要为线程分配不同的优先级,以确保执行时间更长、执行顺序更重要的任务被先处理。这就是优先级队列的作用。

使用线程优先级队列

在Python中,我们可以使用 queue 模块提供的 PriorityQueue 类创建一个线程优先级队列。

队列中每个元素都是一个元组 (priority_number, data),其中 priority_number 是任务的优先级,data 是需要处理的数据。

可以使用 put() 方法将元素添加到队列中:

import queue

q = queue.PriorityQueue()

q.put((3, 'Task 1'))
q.put((1, 'Task 2'))
q.put((2, 'Task 3'))

使用 get() 方法可以从队列中取出队首元素:

while not q.empty():
    task = q.get()
    print(task[1])

取出的元素按照优先级从高到低依次输出:

Task 1
Task 3
Task 2

线程优先级队列示例

示例一:模拟抢购场景

假设我们需要编写一个程序来模拟抢购场景。有若干个抢购请求正在等待被处理,我们需要按照请求的提交时间顺序和请求的优先级来处理这些请求。

首先,我们需要定义一个请求类 Request,包含优先级和提交时间两个属性:

class Request:
    def __init__(self, priority: int, submit_time: float):
        self.priority = priority
        self.submit_time = submit_time

    def __lt__(self, other):
        if self.priority != other.priority:
            return self.priority < other.priority
        return self.submit_time < other.submit_time

这里我们定义了一个小于号运算符重载方法 __lt__,以便在比较运算中按照要求排序。

其次,我们需要把请求添加进队列中:

import queue

q = queue.PriorityQueue()

# 添加请求
req1 = Request(2, 2.1)
req2 = Request(3, 3.2)
req3 = Request(1, 0.5)
q.put((req1.priority, req1))
q.put((req2.priority, req2))
q.put((req3.priority, req3))

最后,我们需要按照提交时间顺序和优先级处理请求:

# 处理请求
while not q.empty():
    req = q.get()[1]
    print(f'处理请求,优先级:{req.priority},提交时间:{req.submit_time}')

输出结果如下:

处理请求,优先级:1,提交时间:0.5
处理请求,优先级:2,提交时间:2.1
处理请求,优先级:3,提交时间:3.2

示例二:模拟生产者-消费者场景

另一个示例是模拟生产者-消费者场景。我们有若干个生产者,每个生产者可以随机生产一定数量的任务,任务的优先级也是随机的。同时,我们有若干个消费者,每个消费者可以从优先级队列中取出并处理一个任务。

首先,我们需要定义一个任务类 Task,包含任务的数据和优先级:

import random

class Task:
    def __init__(self, data: str):
        self.data = data
        self.priority = random.choice(range(10))

接着,我们需要定义一个生产者函数 producer,用于随机生成一定数量的任务,并将任务添加进队列:

import threading
import time

def producer(q: queue.PriorityQueue):
    for i in range(5):
        task_count = random.randint(1, 5)
        for j in range(task_count):
            task = Task(f'Task {i}-{j}')
            q.put((task.priority, task))
            print(f'生产者-{i} 生成任务:{task.data},优先级:{task.priority}')
        time.sleep(1)
    print('生产者结束')

然后,我们需要定义一个消费者函数 consumer,用于从队列中取出并处理任务:

def consumer(consumer_id: int, q: queue.PriorityQueue):
    while True:
        task = q.get()[1]
        print(f'消费者-{consumer_id} 处理任务:{task.data},优先级:{task.priority}')
        time.sleep(1)

将生产者和消费者加入线程:

threads = []

q = queue.PriorityQueue()

for i in range(3):
    t = threading.Thread(target=consumer, args=(i, q))
    t.start()
    threads.append(t)

t = threading.Thread(target=producer, args=(q,))
t.start()
threads.append(t)

等待所有线程完成:

for t in threads:
    t.join()

输出结果如下:

生产者-0 生成任务:Task 0-0,优先级:9
生产者-2 生成任务:Task 2-0,优先级:9
消费者-0 处理任务:Task 0-0,优先级:9
消费者-1 处理任务:Task 2-0,优先级:9
生产者-0 生成任务:Task 0-1,优先级:1
生产者-1 生成任务:Task 1-0,优先级:3
消费者-2 处理任务:Task 0-1,优先级:1
生产者-0 生成任务:Task 0-2,优先级:0
生产者-1 生成任务:Task 1-1,优先级:2
生产者-1 生成任务:Task 1-2,优先级:3
生产者-2 生成任务:Task 2-1,优先级:3
消费者-0 处理任务:Task 1-0,优先级:3
消费者-2 处理任务:Task 0-2,优先级:0
消费者-1 处理任务:Task 1-1,优先级:2
消费者-1 处理任务:Task 1-2,优先级:3
消费者-0 处理任务:Task 2-1,优先级:3
生产者-2 生成任务:Task 2-2,优先级:1
消费者-1 处理任务:Task 2-2,优先级:1
生产者-0 生成任务:Task 0-3,优先级:4
消费者-2 处理任务:Task 0-3,优先级:4
生产者-1 生成任务:Task 1-3,优先级:6
消费者-0 处理任务:Task 1-3,优先级:6
生产者-0 生成任务:Task 0-4,优先级:2
生产者-2 生成任务:Task 2-3,优先级:9
消费者-1 处理任务:Task 0-4,优先级:2
生产者结束
消费者-2 处理任务:Task 2-3,优先级:9
消费者-0 结束
消费者-1 结束

以上就是线程优先级队列的详细讲解和使用示例。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python线程优先级队列知识点总结 - Python技术站

(0)
上一篇 2023年6月3日
下一篇 2023年6月3日

相关文章

  • 使用 selenium 获取 Chrome Devtools 内容的 Python 脚本

    【问题标题】:Python script using selenium to obtain Chrome Devtools content使用 selenium 获取 Chrome Devtools 内容的 Python 脚本 【发布时间】:2023-04-07 14:15:01 【问题描述】: 我在尝试使用 python 脚本在 Chrome Devtoo…

    Python开发 2023年4月8日
    00
  • 使用Python获取爱奇艺电视剧弹幕数据的示例代码

    使用Python获取爱奇艺电视剧弹幕数据 在本教程中,我们将介绍如何使用Python获取爱奇艺电视剧弹幕数据。我们将使用Python的requests和json库来实现这个功能。以下是一个示例代码,演示如何使用Python获取爱奇艺电视剧弹幕数据: import requests import json def get_danmu_data(tv_id): …

    python 2023年5月15日
    00
  • python 函数中的参数类型

    Python 函数中的参数类型 在 Python 函数中,可以接受多种类型的参数,包括必需参数、默认参数、关键字参数和可变参数。每种不同类型的参数都有自己的特点和使用方法。 必需参数 必需参数是函数定义中的普通参数,也称作“位置参数”,必须按照顺序传递,且在调用函数时必须传递指定数量的参数。 以下是一个求和函数的例子,需要输入两个参数: def add(x,…

    python 2023年6月5日
    00
  • python *args **kwargs 在 que 中使用

    【问题标题】:python *args **kwargs used in a quepython *args **kwargs 在 que 中使用 【发布时间】:2023-04-01 02:10:01 【问题描述】: 所以我在 python 中使用 *args **kwargs 功能已经有一段时间了,我遇到了一个问题,我似乎无法在 stackoverflow…

    Python开发 2023年4月8日
    00
  • 详解OpenCV图像的概念和基本操作

    下面是关于“详解OpenCV图像的概念和基本操作”的完整攻略。 OpenCV图像的概念 图像的表示 在OpenCV中,图像是一个矩阵,具有高度和宽度,并且每个像素的强度用一个值来表示(例如,灰度图像中的像素强度在0到255之间)。对于彩色图像,每个像素通常需要用三个值来表示颜色通道(例如,红绿蓝)。OpenCV中使用的常用图像格式包括: 灰度图像:每个像素由…

    python 2023年5月19日
    00
  • CentOS 7下安装Python3.6 及遇到的问题小结

    CentOS7下安装Python3.6及遇到的问题小结 在CentOS7系统中,安装Python3.6可能会遇到一些问题。本文将详细讲解如何在CentOS7下安装Python3.6总结遇到的问题及解决方法,包括依赖问题、编译问题和两个示例。 安装Python3.6 以下是在CentOS下安装Python3.6的步骤: 安装依赖:使用yum命令安装必的依赖。 …

    python 2023年5月13日
    00
  • Python中os模块的简单使用及重命名操作

    当我们需要对操作系统进行一些高级操作时,Python中的os模块是非常有用的一个模块。os模块提供对操作系统进行访问的接口,以我们能够编写出功能强大的程序。 简单使用 首先,我们需要导入os模块: import os 获取当前工作目录 可以使用os.getcwd()方法获取当前工作目录: import os # 获取当前工作目录 current_dir = …

    python 2023年6月2日
    00
  • python 计算一个字符串中所有数字的和实例

    Python计算一个字符串中所有数字的和实例 计算一个字符串中所有数字的和是常见的需求,在Python中通过正则表达式和内置函数可以轻松实现。 方法一:正则表达式 import re def sum_of_numbers(text): """ 计算字符串中所有数字的和 """ return sum(…

    python 2023年6月5日
    00
合作推广
合作推广
分享本页
返回顶部