Python - 线程调度



Python中的线程调度是决定任何给定时间运行哪个线程的过程。在多线程程序中,多个线程独立执行,允许任务并行执行。但是,Python本身并不直接支持控制线程优先级或调度策略。相反,它依赖于操作系统的线程调度程序。

Python线程被映射到主机操作系统的原生线程,例如类Unix系统上的POSIX线程(pthreads)或Windows线程。操作系统的调度程序管理这些线程的执行,包括上下文切换、线程优先级和调度策略。Python通过threading.Timer类和sched模块提供基本的线程调度功能。

本教程将学习Python中线程调度的基础知识,包括如何使用sched模块调度任务以及如何使用threading.Timer类延迟执行函数。

使用Timer类调度线程

Python threading模块的Timer类允许您安排一个函数在一段时间后被调用。此类是Thread的子类,并用作创建自定义线程的示例。

您可以通过调用其start()方法启动计时器,类似于线程。如果需要,您可以使用cancel()方法在计时器开始之前停止它。请注意,执行操作之前的实际延迟可能与指定的精确间隔不匹配。

示例

此示例演示如何使用threading.Timer()类来调度和管理在Python中执行任务(自定义线程)。

import threading
import time

# Define the event function
def schedule_event(name, start):
   now = time.time()
   elapsed = int(now - start)
   print('Elapsed:', elapsed, 'Name:', name)

# Start time
start = time.time()
print('START:', time.ctime(start))

# Schedule events using Timer
t1 = threading.Timer(3, schedule_event, args=('EVENT_1', start))
t2 = threading.Timer(2, schedule_event, args=('EVENT_2', start))

# Start the timers
t1.start()
t2.start()

t1.join()
t2.join()
# End time
end = time.time()
print('End:', time.ctime(end))

执行上述程序后,将产生以下输出:

START: Tue Jul  2 14:46:33 2024
Elapsed: 2 Name: EVENT_2
Elapsed: 3 Name: EVENT_1
End: Tue Jul  2 14:46:36 2024

使用sched模块调度线程

Python标准库中的sched模块提供了一种调度任务的方法。它实现了一个通用的事件调度程序,用于在特定时间运行任务。它提供了类似于Windows或Linux中任务调度的工具。

sched模块的关键类和方法

sched模块中定义的scheduler()类用于创建调度器对象。以下是类的语法:

scheduler(timefunc=time.monotonic, delayfunc=time.sleep)

调度器类中定义的方法包括:

  • scheduler.enter(delay, priority, action, argument=(), kwargs={}) - 事件可以安排在延迟后或特定时间运行。要使用延迟安排它们,请使用enter()方法。

  • scheduler.cancel(event) - 从队列中删除事件。如果该事件不是当前在队列中的事件,则此方法将引发ValueError。

  • scheduler.run(blocking=True) - 运行所有已安排的事件。

事件可以安排在延迟后或特定时间运行。要使用延迟安排它们,请使用enter()方法,它接受四个参数。

  • 表示延迟的数字

  • 优先级值

  • 要调用的函数

  • 函数的参数元组

示例

此示例演示如何使用sched模块调度事件以便在延迟后运行。它调度两个不同的事件:

import sched
import time

scheduler = sched.scheduler(time.time, time.sleep)

def schedule_event(name, start):
   now = time.time()
   elapsed = int(now - start)
   print('elapsed=',elapsed, 'name=', name)

start = time.time()
print('START:', time.ctime(start))
scheduler.enter(2, 1, schedule_event, ('EVENT_1', start))
scheduler.enter(5, 1, schedule_event, ('EVENT_2', start))

scheduler.run()

# End time
end = time.time()
print('End:', time.ctime(end))

它将产生以下输出

START: Tue Jul  2 15:11:48 2024
elapsed= 2 name= EVENT_1
elapsed= 5 name= EVENT_2
End: Tue Jul  2 15:11:53 2024

示例

让我们来看另一个例子来更好地理解这个概念。此示例使用Python中的sched模块调度一个函数,在4秒延迟后执行加法运算。

import sched
from datetime import datetime
import time

def addition(a,b):
   print("Performing Addition : ", datetime.now())
   print("Time : ", time.monotonic())
   print("Result {}+{} =".format(a, b), a+b)

s = sched.scheduler()

print("Start Time : ", datetime.now())

event1 = s.enter(4, 1, addition, argument = (5,6))
print("Event Created : ", event1)
s.run()
print("End Time : ", datetime.now())

它将产生以下输出

Start Time :  2024-07-02 15:18:27.862524
Event Created :  Event(time=2927111.05638099, priority=1, sequence=0, action=<function addition at 0x7f31f902bd90>, argument=(5, 6), kwargs={})
Performing Addition :  2024-07-02 15:18:31.866381
Time :  2927111.060294749
Result 5+6 = 11
End Time :  2024-07-02 15:18:31.866545
广告