作者:郭震
我们之前探讨过“生成器与迭代器之异步生成器”,了解了生成器的异步用法,接下来的主题将进一步扩展我们对并发编程的理解,专注于 Python 中的“多线程”与“多进程”这两种并发编程模型.
什么是并发编程?
并发编程允许程序同时管理多个任务,这些任务可以相互独立或相互交互.在 Python 中,并发编程主要通过多线程和多进程两种方式实现.两者各有其优缺点和适用场景.
多线程 vs 多进程
多线程
定义:多线程是指在一个进程中同时运行多个线程.线程是进程的一个执行单元,拥有自己的调用栈和局部变量,但可以共享进程中的全局变量和资源. 适用场景:适合 I/O 密集型任务,比如网络请求、文件读写等. 优点:线程间切换的开销较小,占用内存少. 缺点:由于 Python 的全局解释器锁(GIL),在 CPU 密集型任务脚本中,多线程可能无法发挥其优势.
多进程
定义:多进程指的是通过创建多个进程来运行只能.每个进程都有自己的 Python 解释器和内存空间,因此不会受 GIL 的影响. 适用场景:适合 CPU 密集型任务,比如计算密集型操作. 优点:可以充分利用多核 CPU 的优势. 缺点:进程间的通信和切换成本高,内存占用较多.
Python 中的多线程
在 Python 中,我们可以使用 threading
模块来创建和管理线程.以下是一个简单的示例,演示如何使用多线程来执行 I/O 密集型任务.
import threading
import time
def worker(thread_name, duration):
print(f'{thread_name} 开始')
time.sleep(duration)
print(f'{thread_name} 结束')
# 创建线程
threads = []
for i in range(5):
t = threading.Thread(target=worker, args=(f'Thread-{i}', 2))
threads.append(t)
t.start()
# 等待所有线程完成
for t in threads:
t.join()
print("所有线程完成")
在这个示例中,我们创建了 5 个线程,每个线程都会休眠 2 秒,模拟 I/O 操作.通过 join()
方法,我们确保主线程会等待所有子线程完成后再继续执行.
注意事项
数据共享:多线程之间可以共享数据,需要注意线程安全,可以使用 threading.Lock
来防止数据竞争.GIL 的影响:在 CPU 密集型任务中,GIL 可能成为瓶颈.
Python 中的多进程
在 Python 中,可以使用 multiprocessing
模块来创建和管理进程.以下是一个简单的示例,演示如何使用多进程来执行 CPU 密集型任务.
import multiprocessing
import os
import time
def worker(process_name, duration):
print(f'{process_name} (PID: {os.getpid()}) 开始')
time.sleep(duration)
print(f'{process_name} (PID: {os.getpid()}) 结束')
if __name__ == '__main__':
# 创建进程
processes = []
for i in range(5):
p = multiprocessing.Process(target=worker, args=(f'Process-{i}', 2))
processes.append(p)
p.start()
# 等待所有进程完成
for p in processes:
p.join()
print("所有进程完成")
在此示例中,我们创建了 5 个进程,每个进程将在 2 秒后结束.与线程不同,在进程中,我们通过 os.getpid()
获取当前进程的 ID.
注意事项
进程间通信:Python 的 multiprocessing
提供了Queue
,Pipe
等方式进行进程间通信.共享数据:通过 Value
或Array
实现简单的数据共享.
小结
在本文中,我们探讨了 Python 的多线程和多进程模型,了解各自的优缺点及适用场景.多线程适合 I/O 密集型任务,而多进程更适合 CPU 密集型任务.掌握这两种并发模型将为后续使用 asyncio
模块打下良好的基础.
长按上图二维码查看「郭震AI学习星球」
更多、数据分析、爬虫、前后端开发、人工智能等教程参考. 以上全文,欢迎继续点击阅读原文学习,阅读更多AI资讯,[请点击这里] https://zglg.work/