编程与数学 02-017 Python 面向对象编程 24课题、并发编程
编程与数学 02-017 Python 面向对象编程 24课题、并发编程
摘要:本文介绍了 Python 并发编程的三种主要方式:多线程、多进程和异步编程。多线程适用于 I/O 密集型任务,通过线程池管理资源;多进程突破了 GIL 限制,适合 CPU 密集型任务,进程池可优化资源管理;异步编程基于事件循环,适合大规模 I/O 密集型任务,支持异步上下文管理和异步 I/O。文中通过示例代码展示了每种并发模型的使用方法,并强调了线程安全、资源管理和异常处理的重要性。
关键词:Python 并发编程;多线程;多进程;异步编程;线程池;进程池;异步 I/O
人工智能助手:Kimi
一、多线程(Threading)
多线程是并发编程中最常见的技术之一。Python 的 threading 模块提供了线程的基本功能,允许程序同时运行多个线程。
线程的基本使用
线程可以用于执行耗时的操作,例如文件 I/O、网络请求等,从而避免阻塞主线程。
示例代码:
import threading
import time
class MyThread(threading.Thread):
def __init__(self, name, duration):
super().__init__()
self.name = name
self.duration = duration
def run(self):
print(f"Thread {self.name} is starting.")
time.sleep(self.duration)
print(f"Thread {self.name} has finished.")
# 创建线程
thread1 = MyThread("Thread-1", 2)
thread2 = MyThread("Thread-2", 3)
# 启动线程
thread1.start()
thread2.start()
# 等待线程完成
thread1.join()
thread2.join()
print("All threads have finished.")
输出:
Thread Thread-1 is starting.
Thread Thread-2 is starting.
Thread Thread-1 has finished.
Thread Thread-2 has finished.
All threads have finished.
线程同步
多线程编程中,线程之间可能会共享资源,这可能导致数据竞争和线程安全问题。Python 提供了多种同步机制,如锁(Lock)、信号量(Semaphore)、事件(Event)等。
示例代码:
import threading
class Counter:
def __init__(self):
self.value = 0
self.lock = threading.Lock()
def increment(self):
with self.lock:
self.value += 1
# 创建共享资源
counter = Counter()
def worker():
for _ in range(10000):
counter.increment()
# 创建线程
threads = [threading.Thread(target=worker) for _ in range(10)]
# 启动线程
for thread in threads:
thread.start()
# 等待线程完成
for thread in threads:
thread.join()
print(f"Final counter value: {counter.value}")
输出:
Final counter value: 100000
线程池
线程池可以有效地管理线程资源,避免频繁创建和销毁线程的开销。Python 的 concurrent.futures 模块提供了线程池的实现。
示例代码:
import concurrent.futures
import time
def task(n):
print(f"Task {n} is starting.")
time.sleep(n)
return f"Task {n} has finished."
# 创建线程池
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
futures = [executor.submit(task, i) for i in range(1, 4)]
for future in concurrent.futures.as_completed(futures):
print(future.result())
输出:
Task 1 is starting.
Task 2 is starting.
Task 1 has finished.
Task 3 is starting.
Task 2 has finished.
Task 3 has finished.
二、多进程(Multiprocessing)
多线程在 Python 中受到全局解释器锁(GIL)的限制,这意味着在单个 Python 进程中,同一时刻只能有一个线程执行 Python 字节码。为了充分利用多核 CPU 的性能,可以使用多进程。
Python 的 multiprocessing 模块提供了进程的基本功能,允许程序同时运行多个进程。
进程的基本使用
进程可以用于执行 CPU 密集型任务,例如计算密集型操作。
示例代码:
import multiprocessing
import time
def worker(name):
print(f"Process {name} is starting.")
time.sleep(2)
print(f"Process {name} has finished.")
# 创建进程
processes = [multiprocessing.Process(target=worker, args=(f"Process-{i}",)) for i in range(3)]
# 启动进程
for process in processes:
process.start()
# 等待进程完成
for process in processes:
process.join()
print("All processes have finished.")
输出:
Process Process-0 is starting.
Process Process-1 is starting.
Process Process-2 is starting.
Process Process-0 has finished.
Process Process-1 has finished.
Process Process-2 has finished.
All processes have finished.
进程池
进程池可以有效地管理进程资源,避免频繁创建和销毁进程的开销。Python 的 multiprocessing 模块提供了进程池的实现。
示例代码:
import multiprocessing
import time
def task(n):
print(f"Task {n} is starting.")
time.sleep(n)
return f"Task {n} has finished."
# 创建进程池
with multiprocessing.Pool(processes=3) as pool:
results = pool.map(task, range(1, 4))
for result in results:
print(result)
输出:
Task 1 is starting.
Task 2 is starting.
Task 1 has finished.
Task 3 is starting.
Task 2 has finished.
Task 3 has finished.
三、异步编程(Asyncio)
异步编程是一种基于事件循环的并发模型,适用于 I/O 密集型任务。Python 的 asyncio 模块提供了异步编程的支持。
异步函数
异步函数使用 async def 定义,可以使用 await 调用其他异步函数。
示例代码:
import asyncio
async def task(name, duration):
print(f"Task {name} is starting.")
await asyncio.sleep(duration)
print(f"Task {name} has finished.")
async def main():
await asyncio.gather(
task("Task-1", 2),
task("Task-2", 3),
task("Task-3", 1)
)
# 运行异步主函数
asyncio.run(main())
输出:
Task Task-1 is starting.
Task Task-2 is starting.
Task Task-3 is starting.
Task Task-3 has finished.
Task Task-1 has finished.
Task Task-2 has finished.
异步上下文管理器
异步上下文管理器可以用于异步资源的管理,例如异步文件操作或网络连接。
示例代码:
import asyncio
class AsyncContextManager:
async def __aenter__(self):
print("Entering the context.")
return self
async def __aexit__(self, exc_type, exc, tb):
print("Exiting the context.")
async def do_something(self):
print("Doing something inside the context.")
async def main():
async with AsyncContextManager() as manager:
await manager.do_something()
# 运行异步主函数
asyncio.run(main())
输出:
Entering the context.
Doing something inside the context.
Exiting the context.
异步 I/O
asyncio 提供了异步 I/O 的支持,可以用于异步文件操作和网络请求。
示例代码:
import asyncio
async def fetch_data(url):
print(f"Fetching data from {url}")
await asyncio.sleep(2) # 模拟网络请求
return f"Data from {url}"
async def main():
url = "https://example.com"
data = await fetch_data(url)
print(data)
# 运行异步主函数
asyncio.run(main())
输出:
Fetching data from https://example.com
Data from https://example.com
二、并发编程的注意事项
- 线程安全:在多线程环境中,需要使用锁或其他同步机制来避免数据竞争。
- GIL 限制:Python 的全局解释器锁(GIL)限制了多线程的性能,对于 CPU 密集型任务,建议使用多进程。
- 资源管理:在并发编程中,需要合理管理资源,避免资源泄漏。
- 异常处理:在异步编程中,需要正确处理异常,避免程序崩溃。
全文总结
本文详细介绍了 Python 并发编程的三种主要方式:多线程、多进程和异步编程。多线程通过 threading 模块实现,适用于 I/O 密集型任务,但受限于全局解释器锁(GIL),无法充分利用多核 CPU。多进程通过 multiprocessing 模块实现,突破了 GIL 限制,适合 CPU 密集型任务,能够充分利用多核 CPU 的性能。异步编程通过 asyncio 模块实现,基于事件循环,适合大规模 I/O 密集型任务,能够高效处理大量并发的 I/O 操作。文中通过具体的示例代码展示了每种并发模型的使用方法,并强调了线程安全、资源管理和异常处理的重要性。在实际开发中,开发者需要根据具体任务的性质(I/O 密集型或 CPU 密集型)选择合适的并发模型,以提高程序的效率和响应能力。
更多推荐


所有评论(0)