Python支持两种线程编程方式:使用threading模块和使用concurrent.futures模块。下面分别对这两种方式进行详细讲解:
要创建线程,需要导入threading模块,并且创建Thread对象。下面是一个简单的示例,演示如何创建一个线程:
import threading
def worker():
"""线程执行的任务"""
print("Thread started.")
print("Thread finished.")
t = threading.Thread(target=worker)
t.start()
在这个示例中,我们通过定义worker函数来定义线程需要执行的任务。然后,创建Thread对象,把worker函数传递给target参数,最后调用start方法启动线程。
在多线程编程中,线程可能会在没有同步的情况下同时访问共享资源,因此需要进行线程同步。Python提供了多种同步机制,例如锁、信号量等。
下面是一个示例,演示如何使用锁进行线程同步:
import threading
x = 0
lock = threading.Lock() # 创建锁对象
def worker():
global x
for i in range(100000):
lock.acquire() # 获取锁
x += 1
lock.release() # 释放锁
print("Thread finished.")
t1 = threading.Thread(target=worker)
t2 = threading.Thread(target=worker)
t1.start()
t2.start()
t1.join()
t2.join()
print(x)
在这个示例中,我们定义了一个共享资源x,并且创建了一个锁对象。在worker函数中,使用锁进行同步,保证x的操作是原子的。最后我们启动两个线程,让它们同时访问共享资源x,并用join方法等待所有线程结束后再输出x。
concurrent.futures模块是Python3中新增的模块,它提供了更高级的线程池接口,更方便地实现并发执行任务。
要使用concurrent.futures模块,首先需要导入ThreadPoolExecutor类。然后,创建ThreadPoolExecutor对象,指定线程池的大小。下面是一个示例,演示如何创建线程池:
from concurrent.futures import ThreadPoolExecutor
def worker():
"""线程执行的任务"""
print("Task finished.")
with ThreadPoolExecutor(max_workers=2) as executor:
future1 = executor.submit(worker)
future2 = executor.submit(worker)
在这个示例中,我们创建了一个大小为2的线程池,然后通过submit方法提交两个任务。submit方法会返回Future对象,我们可以通过Future对象获取任务的执行结果。
在concurrent.futures模块中,每个任务的执行结果都是通过Future对象获取的。Future对象表示一个异步操作的未来结果,它可以用来查询操作的状态、取消操作等。
下面是一个示例,演示如何处理任务的返回值:
from concurrent.futures import ThreadPoolExecutor
def worker(n):
"""线程执行的任务"""
return n * n
with ThreadPoolExecutor(max_workers=2) as executor:
future1 = executor.submit(worker, 2)
future2 = executor.submit(worker, 3)
print(future1.result()) # 输出4
print(future2.result()) # 输出9
在这个示例中,我们定义了一个worker函数,它会返回传入参数的平方。然后创建了一个大小为2的线程池,并通过submit方法提交两个任务。最后,通过Future对象的result方法获取任务的执行结果,并输出结果。
以上是Python线程的两种编程方式的详细攻略,包括了创建线程、线程同步、处理任务返回值等方面的知识点。