Python 线程

在计算机编程中,线程是操作系统能够进行运算调度的最小单位。线程是比进程更小的单位,一个进程可以包含多个线程,线程在同一进程下共享相同的地址空间。Python 是一种支持多线程的编程语言,通过使用线程,可以让程序在多个任务之间并发执行,提高程序的性能和响应速度。
线程的概念
在讨论 Python 线程之前,我们先来了解一下线程的基本概念。
什么是线程?
线程是程序执行流的最小单元。一个进程可以包含多个线程,这些线程共享相同的内存空间。每个线程都有自己的栈空间,但它们可以访问相同的全局变量和静态变量。线程是轻量级的,创建和销毁线程的开销比进程小。
线程与进程的区别
- 进程是系统资源分配的最小单位,而线程是 CPU 调度的最小单位。
- 进程拥有自己的独立内存空间,而线程共享进程的内存空间。
- 进程之间相互独立,线程之间共享资源。
- 创建和撤销线程的开销比进程小。
Python 线程模块
在 Python 中,线程是由 threading 模块来实现的。通过 threading 模块,我们可以在 Python 中实现多线程编程。下面我们将重点介绍 threading 模块的使用。
使用 threading 模块创建线程
在 Python 中使用 threading 模块创建线程非常简单。下面是一个简单的示例代码,演示了如何使用 threading 模块创建线程。
import threading
import time
def say_hello(name):
for i in range(5):
print(f"Hello, {name}!")
time.sleep(1)
# 创建线程
t1 = threading.Thread(target=say_hello, args=("Alice",))
t2 = threading.Thread(target=say_hello, args=("Bob",))
# 启动线程
t1.start()
t2.start()
# 等待线程结束
t1.join()
t2.join()
print("All threads have finished.")
在上面的示例代码中,我们定义了一个 say_hello 函数,该函数会输出 Hello, {name}! 5 次,每次间隔 1 秒。然后我们通过 threading.Thread 类创建了两个线程,分别传入不同的参数,并通过 start 方法启动线程。最后使用 join 方法等待所有线程结束。
运行上面的代码,你将看到类似如下的输出:
Hello, Alice!
Hello, Bob!
Hello, Alice!
Hello, Bob!
Hello, Alice!
Hello, Bob!
Hello, Alice!
Hello, Bob!
Hello, Alice!
Hello, Bob!
All threads have finished.
线程同步
在多线程编程中,由于线程之间共享资源,可能会出现竞争条件(Race Condition)的问题。为了避免竞争条件,我们需要使用线程同步手段来保证线程间的协调和互斥。以下是一些常用的线程同步手段:
Lock(锁)
import threading
lock = threading.Lock()
counter = 0
def increase():
global counter
for _ in range(1000000):
lock.acquire()
counter += 1
lock.release()
threads = []
for _ in range(10):
t = threading.Thread(target=increase)
t.start()
threads.append(t)
for t in threads:
t.join()
print("Counter:", counter)
在上面的示例代码中,我们创建了一个全局变量 counter,以及一个 threading.Lock 对象 lock。在 increase 函数中,我们使用 lock.acquire() 和 lock.release() 方法来保证对 counter 变量的访问是线程安全的。通过使用锁,我们可以保证在同一时刻只有一个线程可以访问共享资源。
Condition(条件)
import threading
condition = threading.Condition()
queue = []
def produce():
for i in range(10):
with condition:
queue.append(i)
condition.notify()
def consume():
for _ in range(10):
with condition:
while not queue:
condition.wait()
item = queue.pop(0)
print("Consumed", item)
t1 = threading.Thread(target=produce)
t2 = threading.Thread(target=consume)
t1.start()
t2.start()
t1.join()
t2.join()
在上面的示例代码中,我们创建了一个 threading.Condition 对象 condition。在 produce 函数中,我们向队列中添加元素并通过 condition.notify() 通知消费线程。在 consume 函数中,我们通过 condition.wait() 来等待生产者线程的通知。通过使用条件变量,我们可以实现生产者消费者模型。
总结
通过本文的介绍,我们了解了线程的概念和 Python 中线程的基本用法。线程可以让程序实现并发执行,提高程序的性能。在多线程编程中,我们需要注意线程之间的同步与互斥,以避免出现竞争条件。通过合理地设计和使用线程,我们可以更好地实现多任务并发执行的效果。
极客教程