Python并发编程实战
学习目标
通过本课程的学习,学员将掌握Python中并发编程的基本概念和实现方法,包括多线程、多进程和异步IO的使用。学员将能够使用threading、multiprocessing和asyncio模块来编写高效的并发程序,解决实际开发中的性能瓶颈问题。
相关知识点
Python并发编程
学习内容
1 Python并发编程
1.1 多线程编程
多线程编程是实现并发的一种方式,它允许程序同时执行多个任务。在Python中,可以使用threading模块来创建和管理线程。多线程特别适用于I/O密集型任务,如文件操作、网络请求等,因为这些任务在等待I/O操作完成时不会占用CPU资源。
1.1.1 线程的基本使用
在Python中,创建线程非常简单。首先,需要导入threading模块,然后定义一个函数作为线程执行的主体。接下来,创建一个Thread对象,并调用其start()方法来启动线程。
import threading
def print_numbers():
for i in range(1, 6):
print(f"Number: {i}")
# 创建线程
thread = threading.Thread(target=print_numbers)
# 启动线程
thread.start()
# 等待线程完成
thread.join()
在这个例子中,定义了一个函数print_numbers,它打印从1到5的数字。然后,创建了一个线程对象thread,并将其目标设置为print_numbers函数。调用start()方法启动线程,join()方法确保主线程等待该线程完成。
1.1.2 线程同步
在多线程编程中,线程同步是一个重要的概念,它确保多个线程在访问共享资源时不会发生冲突。Python的threading模块提供了多种同步机制,如锁(Lock)、事件(Event)、条件(Condition)等。
import threading
# 创建一个锁
lock = threading.Lock()
def update_counter(counter):
for _ in range(100000):
with lock:
counter[0] += 1
counter = [0]
# 创建两个线程
thread1 = threading.Thread(target=update_counter, args=(counter,))
thread2 = threading.Thread(target=update_counter, args=(counter,))
# 启动线程
thread1.start()
thread2.start()
# 等待线程完成
thread1.join()
thread2.join()
print(f"Final counter value: {counter[0]}")
在这个例子中,定义了一个函数update_counter,它更新一个共享的计数器。为了确保线程安全,使用了一个锁lock。在更新计数器时,使用with lock语句来确保同一时间只有一个线程可以执行该段代码。最后,创建了两个线程来更新计数器,并等待它们完成。
1.2 多进程编程
多进程编程是另一种实现并发的方式,它允许程序同时运行多个进程。与多线程不同,多进程之间不共享内存,因此更适合CPU密集型任务。在Python中,可以使用multiprocessing模块来创建和管理进程。
1.2.1 进程的基本使用
创建进程与创建线程类似,首先需要导入multiprocessing模块,然后定义一个函数作为进程执行的主体。接下来,创建一个Process对象,并调用其start()方法来启动进程。
import multiprocessing
def print_numbers():
for i in range(1, 6):
print(f"Number: {i}")
# 创建进程
process = multiprocessing.Process(target=print_numbers)
# 启动进程
process.start()
# 等待进程完成
process.join()
在这个例子中,定义了一个函数print_numbers,它打印从1到5的数字。然后,创建了一个进程对象process,并将其目标设置为print_numbers函数。调用start()方法启动进程,join()方法确保主线程等待该进程完成。
1.2.2 进程间通信
在多进程编程中,进程间通信是一个重要的概念,它允许进程之间交换数据。Python的multiprocessing模块提供了多种通信机制,如管道(Pipe)、队列(Queue)等。
import multiprocessing
def worker(queue):
for i in range(1, 6):
queue.put(i)
# 创建队列
queue = multiprocessing.Queue()
# 创建进程
process = multiprocessing.Process(target=worker, args=(queue,))
# 启动进程
process.start()
# 从队列中获取数据
for _ in range(5):
print(f"Received: {queue.get()}")
# 等待进程完成
process.join()
在这个例子中,定义了一个函数worker,它将数字1到5放入队列中。然后,创建了一个队列queue,并将其作为参数传递给worker函数。创建了一个进程来执行worker函数,并从队列中获取数据。最后,等待进程完成。
1.3 异步IO编程
异步IO编程是一种高效的并发编程方式,特别适用于I/O密集型任务。在Python中,可以使用asyncio模块来编写异步程序。异步编程的核心概念是协程(Coroutine),它允许程序在等待I/O操作时切换到其他任务,从而提高程序的并发性能。
1.3.1 协程的基本使用
在Python中,协程是使用async和await关键字定义的。async关键字用于定义协程函数,await关键字用于等待协程的完成。
%pip install nest_asyncio
import asyncio
import nest_asyncio
nest_asyncio.apply()
async def print_numbers():
for i in range(5):
print(f"Number: {i}")
await asyncio.sleep(1)
# 使用 asyncio.run() 来运行协程
asyncio.run(print_numbers())
在这个例子中,定义了一个协程函数print_numbers,它打印从1到5的数字,并在每次打印后等待1秒。创建了一个事件循环loop,并使用run_until_complete方法来运行协程。最后,关闭了事件循环。
1.3.2 异步任务的并发执行
在异步编程中,可以使用asyncio.gather函数来并发执行多个协程任务。
import asyncio
async def print_numbers():
for i in range(1, 6):
print(f"Number: {i}")
await asyncio.sleep(1)
async def print_letters():
for letter in 'abcde':
print(f"Letter: {letter}")
await asyncio.sleep(1)
async def main():
await asyncio.gather(print_numbers(), print_letters())
# 使用 asyncio.run 来执行主函数
asyncio.run(main())
在这个例子中,定义了两个协程函数print_numbers和print_letters,分别打印数字和字母。创建了一个事件循环loop,并使用asyncio.gather函数来并发执行这两个任务。最后,关闭了事件循环。
846

被折叠的 条评论
为什么被折叠?



