python 进/线程基础
可以参考另外一位同学写的博客
https://blog.csdn.net/u013210620/article/details/78687028
python 线程池添加的回调函数运行是在哪个线程中?
在Python的concurrent,futures模块中 当你向ThreadPoolExecutor提交任务(即调用submit函数)时,任务会在池中的一个线程中执行。一旦任务完成,任何通过add_ done_callback方法添加的回调函数都会被调用。
这些回调函数是在执行任务的那个线程(即完成工作的工作者线程)中执行的 ,而不是在主线程中。这意味着回调函数的执行是在池中线程的上下文中,以异步方式进行的。因为它们在线程池的工作线程内执行,你仍然需要注意线程安全的问题,尤其是当回调函数尝试访问共享资源或变量时。一定要确保你在回调函数中执行的操作是线程安全的,避免引入党态条件。如果必要,你可以使用锁等同步 原语来保护对共享资源的访问。
多个任务的回调函数是在同一个线程中,还是分别在各自的线程中完成?
当你使用Python的concurrent.futures.ThreadPooLExecutor提交多个任务时,每个任务将被分配到线程池中的一个工作线程中去执行。这些任务可以并行执行 (具体取决于系统的线程调度和可用核心数)。对于这些任务的回调函数,它们是在这些任务完成执行后被调用的。
关于回调函数是在同一个线程中执行,还是在不同的线程中执行,关键点在于:
- 不同任务的回调函数可能会在不同的线程中执行。 每个任务的回调函数是在该任务完成后由执行该任务的线程触发的。(如果两个任务恰好被分配给了线程池中的不同线程,它们的回调函数也会在这些线程中分别执行。
- 相同或相关任务的回调函数可能会在同一个线程中执行 ,如果这些任务恰好被分配给相同的线程。
- 线程池的工作方式是重用线程。 当一个线程完成任务并运行了对应的回调函数之后,这个线程可能会被分配给另一个任务。这意味着,即使多个任务的回调函数可能在逻辑上是相互独立的,它们也可能在物理上由同一个线程(在不同时间点)执行。
总的来说,回调函数是与其对应的任务相关联的,并在任务执行的线程中被调用。不同任务的回调函数可以在不同的线程中执行,这完全取决于任务是如何被线程池中的线程执行的。因此,在编写回调函数时,你应该假设它们可能在多线程环境下运行,并确保任何共享资源的访问都是线程安全的。
talk is cheap,show your code
import concurrent.futures
import threading
import time
def task(n):
thread_name = threading.current_thread().name
if thread_name == "MainThread":
thread_type = "主线程"
else:
thread_type = "子线程"
time.sleep(1)
print(f"执行函数的输入是:{n}, 在 {thread_type} ({thread_name}) 中执行。")
return n
def callback(future):
thread_name = threading.current_thread().name
if thread_name == "MainThread":
thread_type = "主线程"
else:
thread_type = "子线程"
result = future.result()
print(f"回调函数的结果:{result}, 在 {thread_type} ({thread_name}) 中执行。")
# 获取主线程的名称
main_thread_name = threading.current_thread().name
# 使用线程池并为每个任务添加回调函数
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
futures = []
for i in range(5):
future = executor.submit(task, i)
future.add_done_callback(callback)
futures.append(future)
# 等待所有的任务完成
concurrent.futures.wait(futures)
# 程序运行结束
print(f"主程序在 {main_thread_name} 中运行完毕。")