1. 多线程概述
在 Python 中,多线程是指在同一进程中拥有多个并发执行流的情况。与单线程相比,多线程可以提高程序的执行效率,特别是需要进行大量计算、I/O 操作或者等待任务完成的项目中,尤其是在现代计算机中已经使用多核心来执行任务的情况下更为明显。
Python 中的多线程使用 threading 模块。
2. 创建多线程
2.1 创建方式
Python 中创建线程有两种方式,一种是继承 threading.Thread 类并重写 run() 方法,另一种则是调用 threading.Thread() 方法并传入一个可调用对象。这两种方式的结果都是创建一个新的线程。
# 继承 threading.Thread 类并重写 run() 方法创建线程
import threading
class MyThread(threading.Thread):
def run(self):
# 处理任务(重写 run() 方法)
my_thread = MyThread()
my_thread.start()
# 传入可调用对象来创建线程
import threading
def task():
# 处理任务
my_thread = threading.Thread(target=task)
my_thread.start()
2.2 线程执行顺序
线程的执行顺序是由操作系统调度并控制的,这意味着对于同样的多线程代码,可能每次执行得到的结果并不一样。因此,多个线程之间的执行会存在一定的随机性。
3. 线程同步
3.1 多个线程访问同一资源的问题
在多个线程同时访问同一资源(如变量、文件、数据库等)的情况下,可能会导致数据错乱等多种问题。这种情况下,我们需要使用线程同步来保证资源的正确访问和修改。
3.2 Lock(锁)
Python 的 threading 模块提供了 Lock 类来实现线程同步操作,锁可以在多个线程之间控制对资源的访问,从而避免竞争条件。
import threading
lock = threading.Lock()
count = 0
def increment():
global count
lock.acquire()
try:
count += 1
finally:
lock.release()
threads = []
for i in range(100):
thread = threading.Thread(target=increment)
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
print('count:', count)
上面的代码中,我们首先创建了一个 Lock 对象,然后将变量 count 初始化为 0。increment() 函数对 count 进行修改前先使用 lock.acquire() 方法获取锁,修改后使用 lock.release() 方法释放锁。在主程序中,我们创建了 100 个线程,并启动它们。
4. 线程间通信
有时我们需要在多个线程之间进行通信,比如协调不同线程的执行或者交换信息。Python 提供了多种方式来实现线程间通信,其中最常用的是使用 Queue 类。
4.1 Queue
Queue 对象用于在线程之间传递信息,可以使用 put() 和 get() 方法将信息添加到队列里或者取出。
import threading
import queue
q = queue.Queue()
def worker():
while True:
item = q.get()
if item is None:
break
# 处理 item
threads = []
for i in range(4):
thread = threading.Thread(target=worker)
threads.append(thread)
thread.start()
for item in range(100):
q.put(item)
for i in range(4):
q.put(None)
for thread in threads:
thread.join()
上面的代码中,我们首先创建一个 Queue 对象,然后在 worker() 函数中不断使用 q.get() 方法从队列取出一个 item 并对其进行处理。在主程序中,我们将 100 个 item 添加到队列中,然后向队列添加 4 个 None,以表示数量足够。
5. 总结
本文介绍了 Python 中使用多线程的基本知识,包括创建多线程、线程同步、线程间通信等方面。根据任务的不同需求,使用多线程可以提高程序的执行效率。