迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > Python >

Python 线程优先级

作者:迹忆客 最近更新:2023/05/31 浏览次数:

本文旨在解释我们如何在 Python 中使用调度线程使其成为优先级。 在这里,我们将讨论如何在 Python 中安排一个优先级线程,并将其与一个很好的示例程序一起使用。

使用 Python 线程,我们可以同时运行程序的不同部分,使您的程序设计更容易。 如果您了解一些 Python,我们将向您展示如何使用线程来加速您的 Python 程序。


Python 中的线程

线程是同时执行多条指令的能力。 正如我们在本文中探讨的那样,我们可以通过调整调度来确定线程的优先级。

全局解释器锁 (GIL) 用于实现 Python 线程,这意味着无法控制线程的优先级。 使用优先级控制线程需要我们创建一个隐式优先级系统。

在线程中,您可以想象两个(或更多)处理器同时在您的程序上运行,每个处理器执行一个独立的任务。

这非常接近于真实。 每个线程将同时在一个处理器上运行,甚至在不同的处理器上运行。

要同时运行多个任务,您需要一个非标准的 Python 实现,您的代码可能需要用不同的语言编写,或者您可能需要使用具有额外开销的多处理。

Python 的 C 实现并不总是支持线程,因此线程可能无法加速所有任务。 GIL 交互限制了可以同时运行的 Python 线程的数量。

通常,线程是花费大量时间等待外部事件的任务的合适选择。 需要大量 CPU 计算但花费很少时间等待外部事件的问题可能不会像其他问题那样运行得那么快。


控制Python线程的调度优先级

确保我们使用正确版本的 Python 至关重要。 我们专门为本文使用 3.10.4 版。

可以通过在终端中运行以下命令来检查当前安装的 python 版本。

python --version

导入有用的库

下一步是了解什么是线程后,学习如何使用调度优先级来制作线程。 您将在本文中看到的大多数原语都是由 Python 标准库通过线程提供的。

在这个模块中,Thread 提供了一个很好的接口来与线程交互,很好地封装了它们。

现在我们进入程序的下一阶段,导入调度 Python 线程优先级所需的库。

示例代码:

import time
from threading import Thread
from time import sleep

可以通过使用 Thread 实例并告诉它 .start() 来启动一个单独的线程。

示例代码:

import logging
import threading
import time
def the_thread_function(name):
    logging.info("The thread %s: Beginning now", name)
    time.sleep(2)
    logging.info("The Thread %s: Ends", name)
if __name__ == "__main__":
    format = "%(asctime)s: %(message)s"
    logging.basicConfig(format=format, level=logging.INFO,
                        datefmt="%H:%M:%S")
    logging.info("Main    : Now before creating a thread")
    x = threading.Thread(target=the_thread_function, args=(1,))
    logging.info("Main    : Earlier than running threading")
    x.start()
    logging.info("Main    : Now wait for the thread to End")
    # x.join()
    logging.info("Main    : All Finish")

输出:

17:06:51: Main    : Now before creating a thread
17:06:51: Main    : Earlier than running threading
17:06:51: The thread 1: Beginning now
17:06:51: Main    : Now wait for the thread to End
17:06:51: Main    : All Finish
17:06:53: The Thread 1: Ends

在日志语句中,您可以看到主要部分正在创建和启动线程:您通过将参数列表和您希望调用的函数传递给线程来创建线程。

在这种情况下,Thread 被告知运行 thread_function() 并将 1 作为参数传递给它。

在 Python 中使用多线程调度优先级

目前,示例代码仅适用于两个线程,即主线程和您使用 threading Thread 对象启动的线程。 您通常会想要启动许多线程并让它们处理有趣的事情。

接下来,让我们看一个更简单的方法。 让我们从更困难的方式开始。

示例代码:

import logging
import threading
import time
def thread_function(name):
    logging.info("Thread %s: Beginning", name)
    time.sleep(2)
    logging.info("Thread %s: Ending", name)
if __name__ == "__main__":
    format = "%(asctime)s: %(message)s"
    logging.basicConfig(format=format, level=logging.INFO,
                        datefmt="%H:%M:%S")
    threads = list()
    for index in range(3):
        logging.info("Main    : create and start thread %d.", index)
        x = threading.Thread(target=thread_function, args=(index,))
        threads.append(x)
        x.start()
    for index, thread in enumerate(threads):
        logging.info("Main    : Before joining thread %d.", index)
        thread.join()
        logging.info("Main    : thread %d end", index)

输出:

17:09:01: Main    : create and start thread 2.
17:09:01: Thread 2: Beginning
17:09:01: Main    : Before joining thread 0.
17:09:03: Thread 0: Ending
17:09:03: Main    : thread 0 end
17:09:03: Main    : Before joining thread 1.
17:09:03: Thread 1: Ending
17:09:03: Main    : thread 1 end
17:09:03: Main    : Before joining thread 2.
17:09:03: Thread 2: Ending
17:09:03: Main    : thread 2 end

我们启动线程的方式与之前启动线程的方式相同,即创建一个 Thread 对象,然后调用 .start()。 保留 Thread 对象的列表允许程序稍后使用 .join() 等待它们。

当您仔细查看输出时,您会注意到所有三个线程都按照您预期的顺序启动。 然而,在这种情况下,它们以相反的顺序完成!

多次运行将产生和输出不同的订单。 查找 Thread x: Nearing End 消息,告诉您每个 Thread 何时结束。

操作系统决定线程运行的顺序,这是很难预测的。 在算法中使用线程可能(并且很可能会)因运行而异,因此在开发算法时请记住这一点。

Python 提供了几个原语来协调线程并将它们相互协调是一件很棒的事情。 我们将首先了解如何更轻松地管理一组线程。

创建 Worker 类

这个 Worker 类允许我们设置脚本,以便每个线程都可以有它的执行时间。 作为结果的形式,如果一个线程具有更高的优先级,我们将使其他线程休眠更长时间。

Worker 类是一个简单的 MFC 类,可帮助您处理多线程。 任何需要其线程执行工作的对象都继承自 Worker 类。

使用 Do-Work 函数执行长过程 - 然后使用对象上的 Start/Stop/Pause 来执行它。

示例代码:

import time
from threading import Thread
from time import sleep
class Worker(Thread):
  def __init__(self,pri):
    Thread.__init__(self)
    self.pri=pri
  def run(self):
    for i in range(20):
      sleep(1.0*self.pri)
      print (" -thread with priority:",self.pri)
w1=Worker(1.0)
w2=Worker(0.75)
w3=Worker(0.5)
start = time.time()
w1.start()
w2.start()
w3.start()
end = time.time()

作为这一步的一部分,我们已经初始化了工人。 之后,我们创建了多个具有不同优先级的线程。

工作线程现在将按如下方式执行:

Output exceeds the size limit. Open the full output data in a text editor
 -thread with priority: 0.5
 -thread with priority: 0.75
 -thread with priority: 1.0
 -thread with priority: 0.5
 -thread with priority: 0.75
 -thread with priority: 0.5
 -thread with priority: 1.0
 -thread with priority: 0.5
 -thread with priority: 0.75
 -thread with priority: 0.5
 -thread with priority: 1.0
 -thread with priority: 0.75

平均而言,通过查看线程执行的输出跟踪,我们将看到优先级为 0.5 和 0.75 的线程在执行后比优先级为 1.0 的线程被调用的频率更高。

以下示例显示了一个简单的 Python 脚本如何根据优先级调度 Python 线程。

我们现在已经看到了 Python 线程的一些示例,以及如何构建具有多个线程、调度优先级的线程程序,以及它们解决的问题。 还演示了 start()join()time()、工作类和许多其他方法的使用。

我们希望您发现本文有助于理解如何在 Python 中使用线程。

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

Pandas read_csv()函数

发布时间:2024/04/24 浏览次数:254 分类:Python

Pandas read_csv()函数将指定的逗号分隔值(csv)文件读取到 DataFrame 中。

Pandas 追加数据到 CSV 中

发布时间:2024/04/24 浏览次数:352 分类:Python

本教程演示了如何在追加模式下使用 to_csv()向现有的 CSV 文件添加数据。

Pandas 多列合并

发布时间:2024/04/24 浏览次数:628 分类:Python

本教程介绍了如何在 Pandas 中使用 DataFrame.merge()方法合并两个 DataFrames。

Pandas loc vs iloc

发布时间:2024/04/24 浏览次数:837 分类:Python

本教程介绍了如何使用 Python 中的 loc 和 iloc 从 Pandas DataFrame 中过滤数据。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便