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

yizhihongxing

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日

相关文章

  • 利用matplotlib实现根据实时数据动态更新图形

    实现根据实时数据动态更新图形的过程可以分为以下几步: 1. 导入必要的库 首先需要导入必要的库,包括matplotlib、numpy和time,其中matplotlib用于绘图,numpy用于生成数据,time用于控制动态更新图形的间隔时间。 import matplotlib.pyplot as plt import numpy as np import …

    python 2023年5月18日
    00
  • JS中min函数实例讲解

    JS中min函数实例讲解 在JavaScript中,min函数是一个用于获取最小值的内置函数。本文将对min函数进行详细说明和实例讲解。 语法 min函数的语法如下: Math.min([value1[, value2[, …]]]) 参数说明: value1, value2, …: 必选参数,可以传入任意个数的数值或数值变量。 返回值 min函数会…

    python 2023年6月3日
    00
  • 如何在Python中进行二次回归

    在Python中进行二次回归可以使用scikit-learn库中的PolynomialFeatures类和LinearRegression类。 下面是进行二次回归的完整步骤: 1. 导入所需库 import numpy as np import matplotlib.pyplot as plt from sklearn.preprocessing impor…

    python-answer 2023年3月25日
    00
  • Django URL和View的关系说明

    “Django URL 和 View 的关系说明”是一个重要的概念,在 Django 框架中,URL 是用来匹配一个请求到指定的 View 的,因此它们是密切相关的。在这篇攻略中,我们将主要讲解 URL 和 View 之间的关系以及如何在 Django 中使用它们。 Django的URLConfs 首先,我们需要了解Django中的URLConf。URLCo…

    python 2023年5月13日
    00
  • 一文带你搞懂Python中的文件操作

    一文带你搞懂Python中的文件操作 Python中的文件操作是编程中常用的一项操作。这里将介绍Python中文件的读写、创建、删除、重命名等操作。 打开文件 使用Python中的open()函数可以打开文件。其基本格式为: file = open(file_path, mode) 其中,file_path为文件路径,mode为打开文件的模式。 常用的打开文…

    python 2023年5月20日
    00
  • Python实现从文件中加载数据的方法详解

    在Python中,我们可以使用多种方法从文件中加载数据。本文将详细讲解Python实现从文件中加载数据的方法,包括使用内置函数、使用第三方库和自定义方法。同时,我们将提供两个示例,以便更好地理解这些方法的使用。 使用内置函数 Python中的内置函数open()可以用于打开文件,并返回一个文件对象。我们可以使用文件对象的read()方法来读取文件中的数据。以…

    python 2023年5月15日
    00
  • python ubplot使用方法解析

    Python Matplotlib使用方法解析 Matplotlib是一个Python中常用的数据可视化库,其中的ubplot则是其一个常用模块,它提供了多种函数用来创建各种形式的图表,包括条形图、散点图、饼图等,这些图表可帮助我们更好地理解数据。 安装 Matplotlib通常会出现在Python的科学计算环境中,可以通过命令行在终端界面安装: pip i…

    python 2023年6月7日
    00
  • pip报错“ValueError: invalid literal for int() with base 10: ‘3.4’”怎么处理?

    原因 “ValueError: invalid literal for int() with base 10: ‘3.4’” 错误通常是以下原因引起的: 版本号格式错误:如果您的版本号格式不正确,则可能会出现此错误。在这种情况下,您需要检查版本号格式是否正确。 版本号包含非数字字符:如果您的版本号包含非数字字符,则可能会出现此错误。在这种情况下,您需要删除版…

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