在现代计算机程序中,并发执行多个任务变得越来越重要。Python的threading模块为我们提供了在单个进程中创建和管理线程的能力,从而实现并发执行。本文将从threading模块的基本概念入手,逐步深入到更高层的线程接口,帮助大家更好地理解和应用Python的并发编程。
「什么是线程?」
线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程实际运作的基本单位。一个进程可以包含多个线程,它们共享进程的内存空间和系统资源。相比于进程,线程的创建和切换开销更小,因此在需要频繁切换执行任务的场景下,使用线程可以提高程序的效率。
「threading模块基础」
threading模块是Python标准库中用于创建和管理线程的模块。下面是一些常用的类和方法:
Thread类:用于创建新的线程。
start()方法:启动线程。
join()方法:等待线程执行结束。
「示例1:创建和启动线程」
import threading
import time
def task(name):
print(f"线程 {name} 开始执行")
time.sleep(2) # 模拟耗时操作
print(f"线程 {name} 执行结束")
if __name__ == "__main__":
thread1 = threading.Thread(target=task, args=("线程1",))
thread2 = threading.Thread(target=task, args=("线程2",))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print("所有线程执行完毕")
在这个例子中,我们创建了两个线程,分别执行task函数。args参数用于传递参数给task函数。join()方法确保主线程等待所有子线程执行完毕后再继续执行。
「线程同步与锁」
由于多个线程共享进程的内存空间,因此在访问共享资源时可能会出现竞争条件,导致数据不一致。为了解决这个问题,我们需要使用线程同步机制,例如锁。
threading模块提供了Lock类来实现锁的功能。
「示例2:使用锁保护共享资源」
import threading
import time
counter = 0
lock = threading.Lock()
def increment():
global counter
for _ in range(1000000):
with lock: # 获取锁
counter += 1# 临界区
# 释放锁(with语句会自动释放)
if __name__ == "__main__":
thread1 = threading.Thread(target=increment)
thread2 = threading.Thread(target=increment)
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print(f"counter = {counter}")
在这个例子中,我们使用Lock对象lock来保护共享变量counter。with lock:语句会自动获取和释放锁,确保在同一时间只有一个线程可以访问counter,从而避免了竞争条件。
「更高层的线程接口:concurrent.futures」
concurrent.futures模块提供了更高层的接口来管理线程和进程,使得并发编程更加简单和方便。其中,ThreadPoolExecutor类用于管理线程池。
「示例3:使用ThreadPoolExecutor」
import concurrent.futures
import time
def task(n):
time.sleep(1)
return n * n
if __name__ == "__main__":
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor: # 创建一个最多3个线程的线程池
futures = [executor.submit(task, i) for i in range(5)] # 提交5个任务到线程池
for future in concurrent.futures.as_completed(futures): # 遍历已完成的任务
print(future.result()) # 获取任务的结果
在这个例子中,我们使用ThreadPoolExecutor创建了一个线程池,并将多个任务提交到线程池中执行。as_completed()函数可以按完成的顺序返回Future对象,我们可以通过result()方法获取任务的结果。
threading模块是Python并发编程的重要工具。通过本文的介绍,我们学习了threading模块的基本概念、线程的创建和管理、线程同步以及更高层的线程接口concurrent.futures。希望这些知识能够帮助初级工程师更好地理解和应用Python的并发编程,写出更高效的程序。
「进一步学习」
深入理解GIL(全局解释器锁):了解GIL对Python多线程的影响。
使用其他同步原语:例如RLock(可重入锁)、Condition(条件变量)、Semaphore(信号量)等。
学习multiprocessing模块:了解如何使用多进程实现真正的并行。
领取专属 10元无门槛券
私享最新 技术干货