关于python:Python全景系列5-解锁Python并发编程多线程和多进程的神秘面纱揭晓

7次阅读

共计 2906 个字符,预计需要花费 8 分钟才能阅读完成。

欢送来到咱们的系列博客《Python 全景系列》!在这个系列中,咱们将率领你从 Python 的基础知识开始,一步步深刻到高级话题,帮忙你把握这门弱小而灵便的编程语法。无论你是编程老手,还是有肯定根底的开发者,这个系列都将提供你须要的常识和技能。

这是本系列的第五篇,咱们将深入探讨 Python 中的并发编程,特地关注多线程和多过程的利用。咱们将先从基本概念开始,而后通过具体举例探讨每一种机制,最初分享一些实战经验以及一种优雅的编程技巧。

第一局部:多线程介绍

线程是操作系统中最小的执行单元。在单个程序或过程内,能够并发运行多个线程,共享过程的资源,如内存和文件描述符。

1.1 Python 中的多线程

Python 反对多线程编程,并提供了 threading 模块作为反对。这个模块提供了 Thread 类,咱们能够通过创立其实例并向其传递函数来创立新线程。当然,你也能够通过继承 Thread 类并重写 run() 办法来创立自定义线程。上面是一个多线程编程的例子:

import threading

def print_numbers():
    for i in range(10):
        print(i)

def print_letters():
    for letter in 'abcdefghij':
        print(letter)

# 创立线程
t1 = threading.Thread(target=print_numbers)
t2 = threading.Thread(target=print_letters)

# 启动线程
t1.start()
t2.start()

# 期待线程完结
t1.join()
t2.join()

在下面的例子中,咱们定义了两个函数:一个打印数字,另一个打印字母。而后咱们创立了两个线程,每个线程的指标是执行这些函数。start()办法用于启动线程,而 join() 办法用于期待线程实现。

1.2 多线程的理论利用

只管 Python 的多线程因为全局解释器锁(GIL)的存在,并不能实现真正的并行,然而它们在 I / O 密集型工作中依然很有用。GIL 是 CPython 解释器的一个互斥锁,保障在任何时刻只有一个线程在执行。这意味着在 CPU 密集型工作中,多线程可能不是最佳抉择,因为它们无奈充分利用多核 CPU。

然而,在 I / O 密集型工作中,多线程可能进步程序性能。例如,如果一个程序须要从多个源下载文件,那么应用多线程能够使得当一个线程期待网络响应时,其余线程能够持续下载其余文件。这样,程序能够在同一时间从多个源下载文件,大大提高了效率。

第二局部:多过程介绍

过程是操作系统中独立的执行实体,每个过程都有本人的内存空间、文件描述符等资源。与线程不同,过程之间的资源

并不共享,每个过程都有本人独立的资源。

2.1 Python 中的多过程

Python 通过 multiprocessing 模块提供了多过程反对。相似于多线程,咱们能够通过创立 Process 类的实例并向其传递函数来创立新过程。咱们也能够通过继承 Process 类并重写 run() 办法来创立自定义过程。

以下是一个简略的多过程编程的例子:

import multiprocessing

def print_numbers():
    for i in range(10):
        print(i)

def print_letters():
    for letter in 'abcdefghij':
        print(letter)

# 创立过程
p1 = multiprocessing.Process(target=print_numbers)
p2 = multiprocessing.Process(target=print_letters)

# 启动过程
p1.start()
p2.start()

# 期待过程完结
p1.join()
p2.join()

这个例子和后面的多线程例子相似,不同的是这里咱们创立的是两个过程,而不是线程。

2.2 多过程的理论利用

多过程能够实现真正的并行,使得 Python 程序能够利用多核 CPU。因而,对于 CPU 密集型工作,多过程通常比多线程更有劣势。另一方面,多过程的开销比多线程大,而且过程间的通信和同步也比线程间的更为简单。因而,对于 I / O 密集型工作,或者须要频繁通信的工作,多线程可能会是更好的抉择。

第三局部:优化并发编程的技巧

在 Python 中,concurrent.futures模块为多线程和多过程编程提供了高级接口,能够让咱们更加简洁地编写代码。

这个模块提供了 ThreadPoolExecutorProcessPoolExecutor两个类,它们别离用于创立线程池和过程池。这两个类都实现了雷同的接口,你能够应用 submit() 办法提交工作,而后应用 as_completed() 函数期待工作实现。

上面是一个应用 concurrent.futures 模块的示例:

import concurrent.futures

def print_numbers():
   for i in range(10):
       print(i)

def print_letters():
   for letter in 'abcdefghij':
       print(letter)

# 应用线程池
with concurrent.futures.ThreadPoolExecutor() as executor:
   future1 = executor.submit(print_numbers)
   future2 = executor.submit(print_letters)
   for future in concurrent.futures.as_completed([future1, future2]):
       pass

# 应用过程池
with concurrent.futures.ProcessPoolExecutor() as executor:
   future1 = executor.submit(print_numbers)
   future2 = executor.submit(print_letters)
   for future in concurrent.futures.as_completed([future1, future2]):
       pass

在下面的例子中,咱们创立了线程池和过程池,而后向它们提交工作。能够看到,应用 concurrent.futures 模块,咱们的代码更加简洁,易读性和可维护性也有所提高。

总结

Python 的多线程和多过程都是十分弱小的工具,能够帮忙咱们编写出更高效的程序。然而,它们也各有优缺点,须要咱们依据具体的工作和需要来抉择。同时,Python 还提供了 concurrent.futures 模块,能够使咱们的并发编程变得更加简略和高效。

咱们心愿本文能帮忙你更好地了解和应用 Python 的多线程和多过程。如果你有任何疑难或者倡议,欢送在评论区留言。

【第一工夫取得 Python 全视角更新信息,请关注自己微信公众号: Python 全视角】

如有帮忙,请多关注
集体微信公众号:【Python 全视角】
TeahLead_KrisChang,10+ 年的互联网和人工智能从业教训,10 年 + 技术和业务团队治理教训,同济软件工程本科,复旦工程治理硕士,阿里云认证云服务资深架构师,上亿营收 AI 产品业务负责人。

正文完
 0