一个线程中总共3个串行任务,在另一个线程中展示任务进行的实施进度。
在一个线程中执行三个串行任务,同时在另一个线程中展示这些任务的实施进度,而不使用队列(queue
),这确实是一个有趣的挑战。不过,我们可以通过共享变量和线程间通信(如使用条件变量或事件)来实现这一点。
在这个例子中,我们将使用threading
模块中的Thread
类来创建工作线程和进度展示线程。工作线程将执行三个串行任务,并通过一个共享变量来更新进度。进度展示线程将定期检查这个共享变量并打印进度。
由于Python的GIL(全局解释器锁)和线程间的同步需求,我们将使用threading.Lock
来确保对共享变量的安全访问。不过,请注意,在这个特定的串行任务场景中,实际上并不需要锁来同步对共享变量的访问,因为只有一个线程会修改它(即工作线程)。但是,为了展示如何在多线程环境中安全地访问共享资源,我们仍然会包含锁的使用。
以下是实现这一功能的代码示例:
import threading
import time
# 共享变量和锁
progress = 0
progress_lock = threading.Lock()
# 条件变量用于通知进度展示线程
progress_condition = threading.Condition()
# 串行任务函数
def execute_tasks():
global progress
tasks = [
("Task 1", 3),
("Task 2", 2),
("Task 3", 4)
]
for task_name, steps in tasks:
for step in range(1, steps + 1):
time.sleep(1) # 模拟任务执行时间
with progress_lock:
progress = (sum(t[1] for t in tasks[:tasks.index((task_name, steps)) + 1]) + step) / sum(t[1] for t in tasks) * 100
with progress_condition:
progress_condition.notify() # 通知进度展示线程
# 进度展示函数
def show_progress():
global progress
while True:
with progress_condition:
progress_condition.wait() # 等待进度更新
with progress_lock:
print(f"Progress: {progress:.2f}%")
# 为了避免过于频繁的打印,这里加一个小的休眠时间
time.sleep(0.5)
# 检查是否所有任务都已完成(这里通过检查进度是否达到100%来模拟)
# 在实际场景中,可能需要一个更明确的完成标志
if progress >= 100:
break
# 创建线程
task_thread = threading.Thread(target=execute_tasks)
progress_thread = threading.Thread(target=show_progress)
# 启动线程
task_thread.start()
progress_thread.start()
# 等待任务线程完成
task_thread.join()
# 停止进度展示线程(这里通过设置一个额外的条件或标志来优雅地停止线程可能更合适,但为了简化示例,我们直接强制终止)
# 注意:在实际应用中,强制终止线程通常不是一个好的做法,因为它可能导致资源泄露或不一致的状态
# 这里我们只是为了演示目的而这样做
progress_thread.join(timeout=1) # 等待1秒以确保至少打印了一些进度信息,然后强制终止
if progress_thread.is_alive():
progress_thread._stop() # 这是一个非公开的方法,仅用于演示目的,不建议在生产代码中使用
print("All tasks completed and progress thread stopped (forcefully in this example).")
重要说明:
-
强制终止线程:在上面的代码中,我们使用了
_stop()
方法来强制终止进度展示线程。这是一个非公开的方法,仅用于演示目的,并且在实际应用中通常不建议使用,因为它可能导致资源泄露或不一致的状态。在实际场景中,应该使用更优雅的线程停止机制,比如通过设置一个明确的停止标志或使用守护线程(daemon thread
)。 -
进度计算:在这个例子中,我们简单地通过计算已完成步骤的总数和总步骤数的比例来估算进度。然而,在实际应用中,进度计算可能会更加复杂,并且可能需要更精确的控制。
-
线程同步:尽管在这个串行任务场景中实际上不需要对共享变量进行复杂的同步操作(因为只有一个线程会修改它),但我们仍然包含了锁和条件变量的使用来展示如何在多线程环境中安全地访问共享资源。在真正的并行或并发环境中,这些同步机制将是必不可少的。
-
代码优化:上面的代码示例是为了演示目的而编写的,并且包含了一些在实际应用中可能不需要或应该避免的做法(如强制终止线程)。在实际项目中,应该根据具体需求和环境对代码进行优化和修改。
以上为AI提供,仅作学习使用。