Python中异步执行的进程与线程异同说明

  1. CPython 实现细节: 在 CPython 中,由于存在 全局解释器锁,同一时刻只有一个线程可以执行 Python 代码(虽然某些性能导向的库可能会去除此限制)。 如果你想让你的应用更好地利用多核心计算机的计算资源,推荐你使用 multiprocessing 或 concurrent.futures.ProcessPoolExecutor。 但是,如果你想要同时运行多个 I/O 密集型任务,则多线程仍然是一个合适的模型。
  2. concurrent.futures.ProcessPoolExecutor 提供了一个更高层级的接口用来将任务推送到后台进程而不会阻塞调用方进程的执行。 与直接使用 Pool 接口相比,concurrent.futures API 能更好地允许将工作单元发往无需等待结果的下层进程池。
  3. concurrent.futures 模块提供异步执行可调用对象高层接口。这是今天的重点。因为我的代码使用到了它。异步执行可以由 ThreadPoolExecutor 使用线程或由 ProcessPoolExecutor 使用单独的进程来实现。 两者都是实现抽象类 Executor 定义的接口。
  4. ThreadPoolExecutorProcessPoolExecutor都是Python的concurrent.futures模块中的执行器(Executor),它们用于创建不同类型的工作池来执行并行任务。它们之间的主要区别在于它们如何处理任务和使用系统资源:
with ThreadPoolExecutor(max_workers=os.cpu_count()) as executor:
        results, dir_count, file_count, size_sum = executor.map(tree, Path(directory).iterdir())
        # Write results to Excel file after processing all subdirectories
        write_to_excel(results, output_file_path)

(补充:在使用ThreadPoolExecutorexecutor.map进行并行遍历时,需要一些逻辑来确保不会有重复的遍历和结果。1、如果有4个executor实例并行执行tree函数,为了避免混乱,需要确保每个实例处理的目录范围不重叠。这通常通过将目录分割成不同的子目录,并将每个子目录分配给不同的executor实例来实现。2、如果正确地分配了任务,results中不应该有重复的内容。每个executor实例应该返回其独立处理的目录的结果。这是一个风险)

在选择使用ThreadPoolExecutor还是ProcessPoolExecutor时,需要考虑任务的性质:

  • 如果任务主要是等待外部资源,如网络请求或磁盘I/O,那么使用ThreadPoolExecutor更合适,因为线程切换的开销比进程小,且可以共享内存。
  • 如果任务是计算密集型的,需要大量的CPU时间,那么使用ProcessPoolExecutor更合适,因为它可以充分利用多核处理器的优势,避免GIL的限制。

总的来说,选择哪种执行器取决于任务的类型和需要优化的资源(CPU还是I/O)。

二、ThreadPoolExecutorsubmit方法和map方法都用于提交任务给线程池执行,但它们在处理任务时有一些关键的区别:

  1. 任务提交方式:

    • submit方法是非阻塞的,它会立即返回一个Future对象,代表异步执行的操作。您可以使用这个Future对象来查询任务的状态和结果。
    • map方法则是阻塞的,它会等待所有任务完成,并返回一个结果列表。这使得map方法更适合批量处理那些相互独立且耗时相似的任务。
  2. 结果处理:

    • 使用submit方法时,您需要手动处理每个Future对象以获取结果。
    • map方法会自动处理结果,按照任务提交的顺序返回结果。
  3. 异常处理:

    • submit方法允许您对每个Future对象单独进行异常处理。
    • map方法会等到所有任务尝试执行完毕后,才会抛出第一个遇到的异常。
  4. 负载均衡:

    • submit方法更灵活,适合于负载不均匀的情况。您可以在任务完成后继续向线程池提交新任务,实现动态的负载均衡。
    • map方法则是一次性提交所有任务,适用于负载相对均匀的场景。

总的来说,如果需要更细粒度的控制,或者任务的复杂度和耗时各不相同,那么submit方法可能是更好的选择。如果您有一组相似的任务需要批量处理,并且希望简化结果的处理,那么map方法可能更适合。

三、线程(Thread)和进程(Process)是计算机操作系统中用于执行任务的两种基本单位。它们之间的关系和区别如下:

  • 关系:

    • 线程是进程的一部分,一个进程可以包含一个或多个线程。
    • 线程是进程中的实际执行单位,它们共享进程的资源,如内存和文件句柄。
  • 区别:

总的来说,进程提供了资源隔离和安全性,而线程提供了执行效率和方便的通信方式。在设计应用程序时,根据任务的特点选择使用进程还是线程非常重要。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值