1. 简介
Python是一种面向对象的、解释型的、具有动态语义的高级编程语言。它提供了许多内置的模块,使得我们可以快速地创建异步程序,其中之一就是thread模块。本文将介绍如何使用Python 2.x中的thread模块来创建和管理线程。
2. 线程概述
线程是一种轻量级的执行单元,它与进程共享内存区域,可以在同一时间内执行多个任务。相较于进程,线程的创建、上下文切换等操作的开销要小得多。
3. 创建线程
可以使用thread库中的start_new_thread()
函数来创建一个新的线程。
3.1. 语法
thread.start_new_thread(function, args[, kwargs])
function: 即将运行在新线程中的函数。
args: 是一个元组类型的参数列表。
kwargs: 是一个字典类型的参数列表。
3.2. 实例:创建线程
import thread
import time
# 定义一个函数,接受两个参数
def print_time(threadName, delay):
counter = 0
while counter < 3:
time.sleep(delay)
print("%s: %s" % (threadName, time.ctime(time.time())))
counter += 1
# 创建两个线程
try:
thread.start_new_thread(print_time, ("Thread-1", 1))
thread.start_new_thread(print_time, ("Thread-2", 2))
except:
print("Error: 无法启动线程")
while True:
pass
以上代码中,我们创建了两个线程并分别将它们命名为“Thread-1”和“Thread-2”。这两个线程分别执行函数print_time()
,并分别使用1
和2
秒的间隔进行打印。不过请注意,上述代码中,主程序无法退出,除非手动停止。
4. 线程同步
由于线程共享全局变量,因此在程序并发运行时可能会导致数据冲突。线程同步机制可以使用lock(锁)来保护数据的完整性。
4.1. 实例:使用锁同步线程
import threading
import time
# 定义一个全局变量
balance = 0
# 创建锁对象
lock = threading.Lock()
# 定义一个函数,将锁作为参数传入
def change_balance(n, lock):
global balance
lock.acquire() # 获取锁
balance = balance + n
balance = balance - n
lock.release() # 释放锁
# 创建两个线程
t1 = threading.Thread(target=change_balance, args=(1, lock))
t2 = threading.Thread(target=change_balance, args=(2, lock))
# 启动线程
t1.start()
t2.start()
# 等待线程执行完毕
t1.join()
t2.join()
# 打印最终结果
print(balance)
在上面的代码中,我们首先创建了一个全局变量balance
,然后创建一个锁对象。然后,我们定义了一个线程函数change_balance()
,该函数接受两个参数:要增加或减少的金额和锁对象。当一个线程需要修改balance
时,它必须首先获取锁,然后对balance
进行操作,最后释放锁。
5. 线程的状态
线程可能处于以下状态之一:
新建状态(New):线程已经创建,但还没有开始运行。
运行状态(Running):线程正在运行中。
阻塞状态(Blocked):线程等待某个条件的发生(如等待I/O操作完成)。
死亡状态(Dead):线程已经执行完毕,结束运行。
6. 线程的控制
线程执行的顺序是不确定的,因为操作系统可能随时调度线程。我们可以使用一些函数来控制线程的行为,这些函数包括:
thread.exit()
: 结束线程。
thread.isStoped()
: 判断线程是否停止。
thread.abortMain()
: 中止主线程。注意:该函数仅适用于主线程。
thread.get_ident()
: 获取当前线程的标识符。
7. 总结
本文介绍了Python 2.x中如何使用thread模块来创建和管理线程,并且介绍了线程同步、线程状态和线程控制等相关内容。线程在Python中是很重要的话题,因为它让我们能够同时执行多个任务,提高了程序的效率。同时,由于线程共享全局变量,因此需要使用线程同步机制来保证数据的一致性。