Python threading.Thread() 线程使用详解:创建、参数传递与守护线程
本文详解Python中threading模块的使用,涵盖线程基本概念、Thread类创建方法、args与kwargs参数传递技巧、线程数量查看及执行顺序特性。重点解析守护线程(Daemon Thread)的设置与行为,通过代码示例展示主线程退出时子线程的终止机制,帮助开发者掌握多线程并发编程的核心要点。
线程的基本概念
1. 线程的基本概念
线程,常被称为轻量级进程(Lightweight Process,LWP),是操作系统进行资源调度和分配的基本单位,也是程序执行流中最小的单元。一个标准线程包含线程ID、当前指令指针(PC)、寄存器集合以及堆栈。作为进程的一个实体,线程本身不拥有系统资源,仅保留运行所必需的少量资源,但它可以与同属一个进程的其他线程共享进程拥有的全部资源。
threading.Thread() 的基础使用
2. threading.Thread() 的基础使用
2.1 模块说明:Python 提供了底层的 thread 模块,而 threading 模块则是对 thread 进行了更高级的封装,使得多线程编程更加便捷和易用。
import threading
import time
def saySorry():
print("亲爱的,我错了,我能吃饭了吗?")
time.sleep(1)
if __name__ == "__main__":
for i in range(5):
t = threading.Thread(target=saySorry)
t.start() #启动线程,即让线程开始执行
运行结果示例

使用说明与注意事项
- 通过对比可以发现,使用多线程并发执行任务时,总耗时通常远少于单线程顺序执行的时间。
- 需要注意的是,只有调用 start() 方法时,才会真正创建操作系统级别的线程,并开始执行目标函数。
- 每个线程都拥有一个唯一的标识符,用于区分线程之间的主次关系及身份。
- 主线程:即 mainThread,对应程序的 Main 函数或主入口点,负责启动整个程序流程。
- 子线程:使用 threading.Thread() 创建出来的线程均被视为子线程,通常标记为 Thread-x 格式。
- 线程总数:等于主线程数量加上所有子线程数量的总和。
2.2 主线程与子线程的生命周期关系:默认情况下,主线程会等待所有已启动的子线程执行完毕后,主进程才会结束。
import threading
from time import sleep,ctime
def sing():
for i in range(3):
print("正在唱歌...%d"%i)
sleep(1)
def dance():
for i in range(3):
print("正在跳舞...%d"%i)
sleep(1)
if __name__ == '__main__':
print('---开始---:%s'%ctime())
t1 = threading.Thread(target=sing)
t2 = threading.Thread(target=dance)
t1.start()
t2.start()
#sleep(5) # 屏蔽此行代码,试试看,程序是否会立马结束?
print('---结束---:%s'%ctime())

3. 查看当前线程数量
import threading
from time import sleep,ctime
def sing():
for i in range(3):
print("正在唱歌...%d"%i)
sleep(1)
def dance():
for i in range(3):
print("正在跳舞...%d"%i)
sleep(1)
if __name__ == '__main__':
print('---开始---:%s'%ctime())
t1 = threading.Thread(target=sing)
t2 = threading.Thread(target=dance)
t1.start()
t2.start()
while True:
length = len(threading.enumerate())
print('当前运行的线程数为:%d'%length)
if length<=1:
break
sleep(0.5)

线程参数传递及执行顺序控制
4. 线程参数传递及执行顺序控制
4.1 参数传递的几种方式
- 使用 args 元组传递参数:例如 threading.Thread(target=sing, args=(10, 100, 100)),参数按位置顺序传递。
- 使用 kwargs 字典传递参数:例如 threading.Thread(target=sing, kwargs={"a": 10, "b": 100, "c": 100}),通过键值对指定参数。
- 同时使用 args 和 kwargs:例如 threading.Thread(target=sing, args=(10, ), kwargs={"b": 100, "c": 100}),需确保参数不冲突且顺序正确。
4.2 线程的执行顺序特性
import socket
import threading
import time
def sing():
for i in range(10):
print("------------------------------")
time.sleep(0.5)
def dance():
for i in range(10):
print("-----")
time.sleep(0.5)
if __name__ == '__main__':
# 创建两个子线程
t1 = threading.Thread(target=sing)
t2 = threading.Thread(target=dance)
# 启动子线程
t1.start()
t2.start()
关键说明
从代码逻辑和执行结果可以看出,多线程程序的执行顺序是不确定的。当线程遇到 sleep 语句时,该线程会进入阻塞(Blocked)状态;sleep 结束后,线程转为就绪(Runnable)状态,等待 CPU 调度。调度器会自主选择下一个执行的线程。虽然代码能保证每个线程最终都会执行完其 run 函数,但线程的启动顺序以及 run 函数内部循环的执行顺序均无法预先确定。
守护线程(Daemon Thread)详解
5. 守护线程(Daemon Thread)详解
守护线程:若在程序中通过 setDaemon(True) 将子线程设置为守护线程,则该子线程会随主线程的结束而自动终止。设置必须在 thread.start() 之前完成,默认值为 False,即主线程结束时,非守护子线程仍会继续执行。
5.1 示例分析:以下代码中,主线程调用了 exit()(实际上并未立即彻底终止所有资源清理),而子线程仍在继续执行其任务。
import threading
import time
def test():
for i in range(10):
print("test is run:", i)
time.sleep(1)
if __name__ == '__main__':
# 创建子线程
t1 = threading.Thread(target=test)
# 启动子线程
t1.start()
# 休眠2秒
time.sleep(2)
print("我 OVER 了")
# 退出
exit()

5.2 如何设置守护线程
设置为守护线程的方法如下: 线程实例.setDaemon(True) 这样设置后,如果主线程结束,子线程也将随之结束。

以上为本文关于 Python threading 模块的完整介绍,希望内容能对各位的学习有所帮助,欢迎持续关注本站获取更多技术更新。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













