Python 线程优先级
本文旨在解释我们如何在 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 中使用线程。
相关文章
Python 线程队列
发布时间:2023/06/01 浏览次数:65 分类:Python
-
本篇文章将介绍限制 Python 中的活动线程数。Python 中的线程 Python 中的线程允许多个执行线程在单个进程中同时运行。
在 Python 中实现最小堆
发布时间:2023/06/01 浏览次数:181 分类:Python
-
本篇文章将介绍最小堆及其在 Python 中的实现。Python 中的最小堆 每个父节点都小于或等于最小堆中的子节点。 它遵循升序,优先级总是与较小的节点。
Python Heapq 窥视
发布时间:2023/06/01 浏览次数:54 分类:Python
-
我们可以使用 heap[0] 表示法、heappop() 函数和 nsmallest() 函数来查看 Python 中堆的最小元素。
Python 中十六进制数的按位异或
发布时间:2023/06/01 浏览次数:109 分类:Python
-
本文的主要目的是演示如何在 Python 的十六进制数字系统中处理 XOR 数字。Python 中十六进制数的按位异或 XOR 是按位运算符,意思是异或。
在 Python 中将十六进制转换为 Base64
发布时间:2023/06/01 浏览次数:85 分类:Python
-
本篇文章将介绍在 Python 中将 hex 转换为 base64 的方法。使用 Python 中的 codecs 模块将 HEX 转换为 BASE64 Python 中的 codecs 模块提供了 encode() 和 decode() 方法来实现不同文本编码格式之间的转换。
Python 中的 Fama-Macbeth 回归
发布时间:2023/06/01 浏览次数:68 分类:Python
-
本篇文章介绍了 Fama-Macbeth 回归、其重要性及其实施。Fama-Macbeth 回归及其重要性 在资产定价理论中,我们使用风险因素来描述资产收益。
Python 逐步回归
发布时间:2023/06/01 浏览次数:75 分类:Python
-
本篇文章将讨论在 Python 中执行逐步回归的方法。Python 中的逐步回归 逐步回归是一种用于统计和机器学习的方法,用于选择特征子集来构建线性回归模型。
Python 错误 ValueError: Cannot Convert Float NaN to Integer
发布时间:2023/05/31 浏览次数:98 分类:Python
-
本篇文章将介绍如何修复 ValueError: cannot convert float NaN to integer 。使用 fillna() 方法修复python错误 ValueError: cannot convert float NaN to integer
修复 Python 错误TypeError: Missing 1 Required Positional Argument
发布时间:2023/05/31 浏览次数:75 分类:Python
-
本篇文章将讨论 Python 中的 TypeError: missing 1 required positional argument: 'self' 错误以及我们如何解决它。让我们讨论引发此错误的情况。不在 Python 中实例化对象