Python多线程编程核心知识点整理
目录前言一、为什么使用多线程二、多线程完成多任务1.多线程完成多任务3.设置主线程结束子线程也结束的方法守护线程三、进程与线程的对比1、关系对比2、区别对比3、优缺点对比四、锁总结前言单线程串行执行会导致程序效率低下无法同时处理多项任务。多线程编程可实现并发执行充分利用计算机资源节省系统开销是Python中提升程序性能的关键技术本文将梳理其核心知识点。一、为什么使用多线程进程是分配资源的最小单位 , 一旦创建一个进程就会分配一定的资源 , 就像跟两个人聊QQ就需要 打开两个QQ软件一样是比较浪费资源的 。线程是程序执行的最小单位 , 实际上进程只负责分配资源 , 而利用这些资源执行程序的是线程 , 也 就说进程是线程的容器 , ⼀个进程中最少有一个线程来负责执行程序 。同时线程自己不拥有系统 资源只需要一点儿在运行中必不可少的资源但它可与同属一个进程的其它线程共享进程所拥有 的全部资源 。这就像通过一个QQ软件(一个进程)打开两个窗口(两个线程)跟两个人聊天一样 , 实现多任务的同时也节省了资源。二、多线程完成多任务1.多线程完成多任务① 导⼊线程模块import threading② 通过线程类创建线程对象线程对象 threading.Thread(groupNone, targetNone, nameNone, args(), kwargs{})target 执行的目标任务名这里指的是函数名(方法名)不能加括号name 进程名一般不用设置group 进程组目前只能使tongNoneargs 传递给 target 任务函数的位置参数必须是元组类型即使只有一个参数也要加逗号如 (10,)kwargs 传递给 target 任务函数的关键字参数必须是字典类型如 {a: 1, b: 2}③ 启动线程执行任务线程对象.start()2.线程创建与启动代码单线程案例import time def music(): for i in range(3): print(听⾳乐...) time.sleep(0.2) def coding(): for i in range(3): print(敲代码...) time.sleep(0.2) if __name__ __main__: music() coding()多线程案例# 导⼊time模块和threading模块 import time import threading # 定义⼀个播放⾳乐的函数 def music(): # 循环三次每次打印听⾳乐的状态并暂停0.2秒 for i in range(3): print(听⾳乐...) time.sleep(0.2) # 定义⼀个编码的函数 def coding(): # 循环三次每次打印敲代码的状态并暂停0.2秒 for i in range(3): print(敲代码...) time.sleep(0.2) # 程序⼊⼝ if __name__ __main__: # 创建⼀个线程⽤于播放⾳乐。通过threading.Thread类创建线程music函数作为线程要执⾏的⽬标。 music_thread threading.Thread(targetmusic) # 创建⼀个线程⽤于编码⼯作。同样使⽤threading.Thread类创建coding函数作为线程要执⾏的⽬标。 coding_thread threading.Thread(targetcoding) # 启动⾳乐线程和编码线程 music_thread.start() coding_thread.start() # 等待⾳乐线程完成其任务 music_thread.join() # 等待编码线程完成其任务 coding_thread.join() print(程序结束)3.设置主线程结束子线程也结束的方法守护线程示例import time import threading def work(): 执⾏⼯作任务的函数。 通过循环模拟⼯作任务的执⾏。每次循环打印⼯作信息并暂停0.2秒 以模拟实际⼯作耗时。 for i in range(10): print(work...) time.sleep(0.2) if __name__ __main__: # 创建⼦线程并设置守护主线程 # 这⾥的守护线程意味着当主线程结束时⼦线程会⾃动结束不需要显式等待⼦线程的结束 work_thread threading.Thread(targetwork, daemonTrue) # 启动线程 work_thread.start() # 延时1s # 这⾥可能是为了模拟⼀些操作需要时间或者给⼦线程⼀些时间来完成它的任务 time.sleep(1) print(主线程执⾏完毕)三、进程与线程的对比特性进程线程定义操作系统分配资源的基本单位进程内的执行单元共享进程资源资源开销高(独立生存、资源)低(共享进程内存)启动速度慢快并发性多核并行(绕过GIL)伪并行(受GIL限制)数据共享需IPC(队列、管道等)直接共享内存(需同步机制)适用场景CPU密集型任务(计算、多核利用)I/O密集型任务(网络、文件操作)模块multiprocessingthreading容错性高(进程崩溃不影响其他进程)低(线程崩溃可能导致进程终止)调试难度较高(需处理IPC)较低(共享数据需同步)1、关系对比① 线程是依附在进程里面的没有进程就没有线程。② 一个进程默认提供一条线程进程可以创建多个线程。2、区别对比① 进程之间不共享全局变量② 线程之间共享全局变量③ 创建进程的资源开销要比创建线程的资源开销要大④ 进程是操作系统资源分配的基本单位线程是CPU调度的基本单位3、优缺点对比① 进程优缺点:优点可以用多核缺点资源开销大② 线程优缺点优点资源开销小缺点不能使用多核四、锁无论是进程还是线程当涉及到共享资源时都需要使用锁来同步访问以避免竞态条件。Python提供 了 Lock 对象来实现这一功能。使用线程锁import threading # 创建⼀个锁对象⽤于在多线程中同步对共享资源的访问 lock threading.Lock() # 定义线程函数该函数将计数器增加n次 def thread_function(n): global counter for _ in range(n): # 打印当前线程将计数器增加到的值 print(f线程 {threading.current_thread().name} 将计数器增加到 {counter}) # 获取锁确保同⼀时间只有⼀个线程在修改counter lock.acquire() try: # 尝试增加计数器 counter 1 finally: # 释放锁允许其他线程进⾏操作 lock.release() # 初始化全局计数器 counter 0 # 初始化线程列表 threads [] # 创建并启动5个线程每个线程都会执⾏thread_function for i in range(5): # 创建线程 t threading.Thread(targetthread_function, args(i,)) # 将线程添加到线程列表中 threads.append(t) # 启动线程 t.start() # 等待所有线程完成执⾏ for t in threads: t.join() # 打印最终的计数器值 print(f最终的计数器值: {counter})总结本文系统梳理了Python多线程编程的核心内容涵盖多线程的应用价值、实现步骤、守护线程用法对比了进程与线程的关键差异并介绍了锁的使用以解决共享资源同步问题为高效运用多线程提升程序性能提供了清晰指引。