摘要本文介绍了Python中实现线程的两种方式_thread模块和threading模块。_thread模块提供基本线程操作而threading模块采用面向对象设计功能更丰富。文章详细说明了如何创建线程、线程状态转换以及守护线程的实现并通过示例代码演示了线程的创建、运行和终止过程。重点对比了_thread.start_new_thread()方法和threading.Thread类的使用方式同时讲解了守护线程的特性及其适用场景。目录Python 中的并发 —— 线程的实现实现线程的 Python 模块_thread 模块示例输出结果模块模块的额外方法如何通过 模块创建线程示例输出结果演示线程各状态的 Python 程序步骤 1导入所需模块 threading 和 time步骤 2定义线程执行的目标函数步骤 3通过 time 模块的 sleep () 方法让线程等待 2 秒步骤 4创建线程实例 T1指定执行的目标函数步骤 5调用 start () 方法启动线程控制台将打印预设的运行状态提示步骤 6线程执行完毕后调用 join () 方法回收线程资源终止线程Python 中启动线程的简易方式输出结果Python 中的守护线程Python 中的并发 —— 线程的实现实现线程的 Python 模块Python 中的线程也被称作轻量级进程因为线程占用的内存远少于进程且能支持程序同时执行多个任务。Python 中提供了两个实现线程的核心模块分别是_thread 模块threading 模块两个模块的核心区别在于_thread模块将线程视作一个函数来处理而 **threading** 模块采用面向对象的设计思路把每个线程都封装为一个对象此外_thread模块仅适用于底层线程操作功能远不如 **threading** 模块丰富。_thread 模块在 Python 早期版本中提供的是 **thread** 模块但该模块已被标记为 “废弃” 许久官方一直推荐开发者使用 **threading** 模块替代。因此在 Python 3 中thread模块被彻底移除为了兼容版本差异重命名为 **_thread** 模块。通过_thread模块创建新线程时需要调用其start_new_thread方法该方法的语法格式如下_thread.start_new_thread ( function, args[, kwargs] )参数说明args传入函数的参数以元组形式传递kwargs可选参数以字典形式为函数传递关键字参数如果调用的函数无需传入参数需将args设置为空元组。该方法调用后会立即返回子线程随即启动并将参数若有传入指定函数执行。当函数执行完毕后对应的子线程也会随之终止。示例以下示例通过_thread模块的start_new_thread()方法创建新线程import _thread import time def print_time( threadName, delay): count 0 while count 5: time.sleep(delay) count 1 print (%s: %s % ( threadName, time.ctime(time.time()) )) try: _thread.start_new_thread( print_time, (Thread-1, 2, ) ) _thread.start_new_thread( print_time, (Thread-2, 4, ) ) except: print (Error: unable to start thread) while 1: pass输出结果以下输出能清晰体现_thread模块创建的多线程执行过程plaintextThread-1: Mon Apr 23 10:03:33 2018 Thread-2: Mon Apr 23 10:03:35 2018 Thread-1: Mon Apr 23 10:03:35 2018 Thread-1: Mon Apr 23 10:03:37 2018 Thread-2: Mon Apr 23 10:03:39 2018 Thread-1: Mon Apr 23 10:03:39 2018 Thread-1: Mon Apr 23 10:03:41 2018 Thread-2: Mon Apr 23 10:03:43 2018 Thread-2: Mon Apr 23 10:03:47 2018 Thread-2: Mon Apr 23 10:03:51 2018threading 模块threading模块采用面向对象的实现方式将每个线程封装为独立对象因此相比 _thread 模块它能为线程操作提供更强大、更高级的支持。该模块从 Python 2.4 版本开始内置在 Python 中。threading 模块的额外方法threading模块包含了 _thread 模块的所有方法同时扩展了更多实用方法新增方法如下threading.activeCount()返回当前处于活动状态的线程对象数量threading.currentThread()返回调用者线程控制中的线程对象threading.enumerate()返回当前所有活动线程对象组成的列表为了实现线程操作threading模块提供了Thread核心类该类包含以下常用方法run()线程的执行入口方法start()启动线程底层会调用 run () 方法join([time])阻塞当前线程等待目标线程执行终止可选参数 time 为超时时间isAlive()判断线程是否仍在执行getName()返回线程的名称setName()设置线程的名称如何通过 threading 模块创建线程通过 threading 模块创建新线程可遵循以下步骤定义Thread类的新子类若需要传入额外参数重写init(self [,args])构造方法重写run(self [,args])方法实现线程启动后需要执行的业务逻辑。创建好Thread子类后即可实例化该类调用start()方法启动新线程该方法会自动调用重写后的run()方法。示例以下示例演示如何通过 threading 模块创建并运行新线程import threading import time exitFlag 0 class myThread (threading.Thread): def __init__(self, threadID, name, counter): threading.Thread.__init__(self) self.threadID threadID self.name name self.counter counter def run(self): print (Starting self.name) print_time(self.name, self.counter, 5) print (Exiting self.name) def print_time(threadName, delay, counter): while counter: if exitFlag: threadName.exit() time.sleep(delay) print (%s: %s % (threadName, time.ctime(time.time()))) counter - 1 # 创建线程实例 thread1 myThread(1, Thread-1, 1) thread2 myThread(2, Thread-2, 2) # 启动线程 thread1.start() thread2.start() # 等待线程执行完毕 thread1.join() thread2.join() print (Exiting Main Thread)输出结果plaintextStarting Thread-1 Starting Thread-2 Thread-1: Mon Apr 23 10:52:09 2018 Thread-1: Mon Apr 23 10:52:10 2018 Thread-2: Mon Apr 23 10:52:10 2018 Thread-1: Mon Apr 23 10:52:11 2018 Thread-1: Mon Apr 23 10:52:12 2018 Thread-2: Mon Apr 23 10:52:12 2018 Thread-1: Mon Apr 23 10:52:13 2018 Exiting Thread-1 Thread-2: Mon Apr 23 10:52:14 2018 Thread-2: Mon Apr 23 10:52:16 2018 Thread-2: Mon Apr 23 10:52:18 2018 Exiting Thread-2 Exiting Main Thread演示线程各状态的 Python 程序线程共有五种状态新建、就绪、运行、等待、终止。本节将重点演示其中三种核心状态运行、等待、终止。线程在运行状态获取并占用系统资源在等待状态释放资源并等待调度执行完成后进入终止状态最终释放所有占用的资源。以下 Python 程序将通过start()、sleep()和join()方法分别演示线程进入运行、等待、终止状态的过程步骤 1导入所需模块 threading 和 timeimport threading import time步骤 2定义线程执行的目标函数def thread_states(): print(Thread entered in running state)步骤 3通过 time 模块的 sleep () 方法让线程等待 2 秒time.sleep(2)步骤 4创建线程实例 T1指定执行的目标函数T1 threading.Thread(targetthread_states)步骤 5调用 start () 方法启动线程控制台将打印预设的运行状态提示T1.start() # 输出Thread entered in running state步骤 6线程执行完毕后调用 join () 方法回收线程资源终止线程T1.join()Python 中启动线程的简易方式Python 中有多种启动线程的方式其中最简便的是将线程逻辑定义为单个函数再将该函数作为目标创建threading.Thread对象即可。执行以下代码理解该方式的实现逻辑import threading import time import random def Thread_execution(i): print(Execution of Thread {} started\n.format(i)) sleepTime random.randint(1,4) time.sleep(sleepTime) print(Execution of Thread {} finished.format(i)) # 循环创建4个线程 for i in range(4): thread threading.Thread(targetThread_execution, args(i,)) thread.start() print(Active Threads:, threading.enumerate())输出结果plaintextExecution of Thread 0 started Active Threads: [_MainThread(MainThread, started 6040), HistorySavingThread(IPythonHistorySavingThread, started 5968), Thread(Thread-3576, started 3932)] Execution of Thread 1 started Active Threads: [_MainThread(MainThread, started 6040), HistorySavingThread(IPythonHistorySavingThread, started 5968), Thread(Thread-3576, started 3932), Thread(Thread-3577, started 3080)] Execution of Thread 2 started Active Threads: [_MainThread(MainThread, started 6040), HistorySavingThread(IPythonHistorySavingThread, started 5968), Thread(Thread-3576, started 3932), Thread(Thread-3577, started 3080), Thread(Thread-3578, started 2268)] Execution of Thread 3 started Active Threads: [_MainThread(MainThread, started 6040), HistorySavingThread(IPythonHistorySavingThread, started 5968), Thread(Thread-3576, started 3932), Thread(Thread-3577, started 3080), Thread(Thread-3578, started 2268), Thread(Thread-3579, started 4520)] Execution of Thread 0 finished Execution of Thread 1 finished Execution of Thread 2 finished Execution of Thread 3 finishedPython 中的守护线程在实现守护线程前需先了解守护线程的概念及使用场景。在计算机领域守护线程是运行在后台的线程主要处理数据发送、文件传输等辅助性服务请求当无任务需要处理时会处于休眠状态。普通的非守护线程也能实现后台任务但主线程需要手动跟踪其状态而守护线程无需主线程管理当主线程退出时所有守护线程会被自动终止。注意守护线程仅适用于非核心任务—— 这类任务即使执行中断、未完成也不会对程序的核心逻辑产生影响。以下是 Python 中守护线程的实现代码import threading import time def nondaemonThread(): print(starting my thread) time.sleep(8) print(ending my thread) def daemonThread(): while True: print(Hello) time.sleep(2) if __name__ __main__: nondaemonThread threading.Thread(target nondaemonThread) daemonThread threading.Thread(target daemonThread) # 将线程设置为守护线程 daemonThread.setDaemon(True) # 启动线程 daemonThread.start() nondaemonThread.start()上述代码中定义了两个函数nondaemonThread()为非守护线程的执行逻辑打印状态后休眠 8 秒再结束daemonThread()为守护线程的执行逻辑无限循环每 2 秒打印一次Hello。通过以下输出可清晰看出守护线程与非守护线程的执行差异plaintextHello starting my thread Hello Hello Hello Hello ending my thread Hello Hello Hello Hello Hello