1. 前言
Python 是一门高级编程语言,支持多线程编程,但是多线程编程时要注意线程之间的执行顺序,否则可能会造成线程之间的竞争条件。
2. Python 中的线程
Python 中的线程有两种方式:
2.1 使用 threading 模块
使用 threading 模块来创建和管理线程。以下是一个简单的例子:
import threading
def worker():
print('Worker')
threads = []
for i in range(5):
t = threading.Thread(target=worker)
threads.append(t)
t.start()
以上代码将会启动 5 个线程执行函数 worker。
2.2 使用 concurrent.futures 模块
concurrent.futures 模块将会更方便的管理线程,以下是一个简单的例子:
from concurrent.futures import ThreadPoolExecutor
def worker():
print('Worker')
with ThreadPoolExecutor(max_workers=5) as executor:
for i in range(5):
future = executor.submit(worker)
以上代码也将会启动 5 个线程执行函数 worker。
3. 改变线程执行顺序
虽然 Python 中的线程可以很方便的创建和管理,但是线程之间的执行顺序是不能控制的,取决于操作系统的调度。但是可以通过一些方式来改变线程的执行顺序。
3.1 使用 join()
join() 方法可以阻塞主线程,等待所有子线程执行完成,以下是一个例子:
import threading
def worker(i):
print(f'Worker {i}')
threads = []
for i in range(5):
t = threading.Thread(target=worker, args=(i,))
threads.append(t)
t.start()
for t in threads:
t.join()
以上代码将会按顺序输出每个工作线程的名称。
3.2 使用锁
锁是一种同步机制,可以防止多个线程同时访问共享资源。以下是一个例子:
import threading
lock = threading.Lock()
counter = 0
def worker():
global counter
lock.acquire()
counter += 1
lock.release()
threads = []
for i in range(5):
t = threading.Thread(target=worker)
threads.append(t)
t.start()
for t in threads:
t.join()
print(f'Counter: {counter}')
以上代码将会对一个计数器进行加一操作,使用锁来控制线程的访问。
3.3 使用条件变量
条件变量是一种同步机制,可以在不同线程间传递信息。以下是一个例子:
import threading
data = None
cv = threading.Condition()
def producer():
global data
with cv:
data = 'Product'
cv.notify_all()
def consumer():
global data
with cv:
while data is None:
cv.wait()
print(data)
threads = []
t1 = threading.Thread(target=producer)
t2 = threading.Thread(target=consumer)
threads.append(t1)
threads.append(t2)
for t in threads:
t.start()
for t in threads:
t.join()
以上代码将会在生产者和消费者之间传递数据。
3.4 使用队列
队列是一种同步机制,可以安全地在多个线程间传递数据。以下是一个例子:
import queue
import threading
q = queue.Queue()
def worker():
while True:
item = q.get()
if item is None:
break
print(item)
q.task_done()
threads = []
for i in range(5):
t = threading.Thread(target=worker)
threads.append(t)
t.start()
for i in range(10):
q.put(f'Item {i}')
q.join()
for i in range(5):
q.put(None)
for t in threads:
t.join()
以上代码将会在多个线程之间安全地传递数据,使用了队列来同步线程的执行顺序。
4. 总结
Python 中的多线程编程可以很方便的创建和管理,但是线程之间的执行顺序是不能控制的。本文介绍了几种改变线程执行顺序的方法,包括使用 join()、锁、条件变量和队列等同步机制。