Python threading模块多线程创建与使用详解
本文详细解析Python中threading模块的多线程创建与使用方法。涵盖普通函数创建、自定义线程类继承两种方式,深入讲解守护线程(Daemon)的设置与行为特性,主线程等待子线程结束的join机制,以及利用互斥锁(Lock)解决资源竞争问题的具体实现。
Python多线程创建基础
在Python并发编程中,多线程是提升程序执行效率的重要手段。threading模块提供了创建和管理线程的核心功能,掌握其创建方法和使用技巧对于开发高效应用至关重要。
创建线程最基础的方式是通过函数直接实例化Thread对象。这种方式适用于逻辑简单的场景,无需额外定义类结构,直接指定目标函数和参数即可启动线程执行任务。
import threading
def run(name):
for i in range(3):
print(name)
if __name__ == '__main__':
t1 = threading.Thread(target=run, args=("t1",))
t2 = threading.Thread(target=run, args=("t2",))
t1.start()
t2.start()
--------------------------------------------
t1
t2
t2
t1
t2
t1
对于需要维护状态或更复杂逻辑的场景,可以通过继承threading.Thread类来创建自定义线程。这种方式允许在子类中重写run方法,并添加额外的属性和初始化逻辑,使线程对象更具扩展性。
import threading
class MyThread(threading.Thread):
def __init__(self, name):
super(MyThread, self).__init__()
self.name = name
def run(self):
for i in range(3):
print(self.name)
if __name__ == "__main__":
t1 = MyThread("t1")
t2 = MyThread("t2")
t1.start()
t2.start()
线程控制与同步机制
线程创建后,如何控制其生命周期和行为是实际开发中的关键问题。主要包括守护线程的设置、主线程与子线程的同步等待,以及多线程访问共享资源时的并发控制。
守护线程是一种特殊类型的线程,其生命周期依赖于主线程。当主线程结束时,无论守护子线程是否执行完毕,都会强制结束。这种机制常用于后台辅助任务,如日志记录或缓存清理。
设置守护线程的核心在于调用setDaemon(True)方法。需要注意的是,该设置必须在调用start()启动线程之前完成,否则将抛出RuntimeError异常。一旦设置为守护线程,子线程将不再阻碍主进程退出。
import threading def run(name): for i in range(3): print(name) if __name__ == '__main__': t1 = threading.Thread(target=run, args=("t1",)) t2 = threading.Thread(target=run, args=("t2",)) t1.start() t2.start() -------------------------------------------- t1 t2 t2 t1 t2 t1
默认情况下,主线程会等待所有非守护子线程执行完毕后才结束。如果希望主线程在特定条件下等待子线程完成,可以使用join()方法。该方法会阻塞主线程,直到调用join()的线程执行结束。
import threading class MyThread(threading.Thread): def __init__(self, name): super(MyThread, self).__init__() self.name = name def run(self): for i in range(3): print(self.name) if __name__ == "__main__": t1 = MyThread("t1") t2 = MyThread("t2") t1.start() t2.start()
多线程资源竞争与互斥锁
当多个线程同时访问共享资源时,可能会发生数据竞争或不一致问题。互斥锁(Lock)是解决此类问题的标准方案。通过acquire()获取锁和release()释放锁,可以确保同一时刻只有一个线程执行临界区代码,从而保证数据一致性。
from threading import Thread,Lock
n = 10
def run():
global n
locker.acquire()
n -= 1
locker.release()
if __name__ == '__main__':
locker = Lock()
t1 = Thread(target=run)
t2 = Thread(target=run)
t1.start()
t2.start()
from threading import Thread,Lock n = 10 def run(): global n locker.acquire() n -= 1 locker.release() if __name__ == '__main__': locker = Lock() t1 = Thread(target=run) t2 = Thread(target=run) t1.start() t2.start()
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













