3.1使用 Lock 实现线程同步
在多线程编程中,为了避免多个线程同时访问共享资源导致数据混乱或不一致的问题,可以使用 Lock
对象实现线程同步。下面是一个简单的示例:
import threading
counter = 0
lock = threading.Lock()
def increment_counter():
global counter
with lock:
counter += 1
# 创建多个线程并启动
threads = []
for _ in range(5):
t = threading.Thread(target=increment_counter)
t.start()
threads.append(t)
# 等待所有线程执行完成
for t in threads:
t.join()
print("Final counter value:", counter)
在上面的示例中,通过 Lock
对象确保了 counter
变量的原子性操作,避免了多线程同时修改导致的问题。
3.2使用 Queue 实现线程间通信
另一种常见的方式是使用 Queue
实现线程间的通信。Queue
是线程安全的数据结构,可以在多个线程之间安全地传递数据。以下是一个简单的示例:
import threading
import queue
def producer(q):
for i in range(5):
q.put(i)
def consumer(q):
while not q.empty():
item = q.get()
print("Consumed:", item)
# 创建队列
q = queue.Queue()
# 创建生产者和消费者线程
producer_thread = threading.Thread(target=producer, args=(q,))
consumer_thread = threading.Thread(target=consumer, args=(q))
# 启动线程
producer_thread.start()
consumer_thread.start()
# 等待线程执行完成
producer_thread.join()
consumer_thread.join()
在上面的示例中,通过 Queue
实现了生产者和消费者模式,生产者向队列中放入数据,消费者从队列中取出数据进行消费,实现了线程间的通信。
4.线程池的使用
使用 ThreadPoolExecutor 可以方便地管理线程池,控制线程数量并提交任务。以下是 ThreadPoolExecutor 的基本用法示例:
from concurrent.futures import ThreadPoolExecutor
import time
# 定义一个任务函数
def task(n):
print(f"Task {n} started")
time.sleep(2)
return f"Task {n} completed"
# 创建 ThreadPoolExecutor
with ThreadPoolExecutor(max_workers=3) as executor: # 控制线程池大小为3
# 提交任务给线程池
future1 = executor.submit(task, 1)
future2 = executor.submit(task, 2)
future3 = executor.submit(task, 3)
# 获取任务执行结果
print(future1.result())
print(future2.result())
print(future3.result())
在上面的示例中,通过 ThreadPoolExecutor
创建了一个最大容纳3个线程的线程池。然后使用 submit()
方法提交了三个任务,并使用