python线程进程的用法实例+讲解
案例 1多线程售票 互斥锁最经典作用多个线程卖同一份票不加锁会超卖、负数加锁就安全。importthreadingimporttime# 共享数据总票数ticket10# 创建互斥锁保证同一时间只有一个线程修改票数lockthreading.Lock()defsale_ticket():globalticketwhileTrue:# 加锁开始操作共享数据lock.acquire()try:ifticket0:time.sleep(0.1)# 模拟出票延迟print(f{threading.current_thread().name}卖出第{ticket}张票)ticket-1# 修改共享数据else:print(f{threading.current_thread().name}票卖完了)breakfinally:# 解锁必须释放否则卡死lock.release()if__name____main__:# 创建2个售票线程t1threading.Thread(targetsale_ticket,name窗口1)t2threading.Thread(targetsale_ticket,name窗口2)t1.start()t2.start()t1.join()t2.join()关键点讲解ticket 10所有线程共享lock threading.Lock()互斥锁lock.acquire()抢占锁抢到才能执行lock.release()释放锁别人才能用try...finally保证无论是否出错锁一定释放案例 2多进程独立、隔离、不共享作用演示进程有独立内存、独立 PID、互不影响。importmultiprocessingimportosimporttimedefprocess_task(name):# 每个进程有自己的PIDprint(f子进程{name}运行PID {os.getpid()})time.sleep(0.5)print(f子进程{name}结束)if__name____main__:# 创建2个进程p1multiprocessing.Process(targetprocess_task,args(A,))p2multiprocessing.Process(targetprocess_task,args(B,))p1.start()# 启动p2.start()p1.join()# 等待结束p2.join()print(主进程结束)关键点讲解每个进程有独立 PID进程之间不共享变量Windows 必须写if __name__ __main__进程开销比线程大但更稳定案例 3进程池 Manager ().Queue 通信作用进程池里的进程必须用 Manager ().Queue 通信普通 Queue 不能用。importmultiprocessingfromconcurrent.futuresimportProcessPoolExecutorimporttimedefpool_task(q,i):# 往队列里放数据q.put(f进程池任务{i}执行完毕)time.sleep(0.3)if__name____main__:# 进程池通信必须用这个队列qmultiprocessing.Manager().Queue()# 创建进程池最多2个进程withProcessPoolExecutor(max_workers2)aspool:foriinrange(3):pool.submit(pool_task,q,i)# 读取结果whilenotq.empty():print(q.get())关键点讲解进程池通信 Manager().Queue()ProcessPoolExecutor进程池submit(函数, 参数1, 参数2...)提交任务进程池自动管理进程创建 / 销毁案例 4线程池工作最常用作用批量处理 IO 任务爬虫、文件、网络高效、轻量。fromconcurrent.futuresimportThreadPoolExecutorimporttimedefthread_task(i):time.sleep(0.2)returnf线程池任务{i}完成if__name____main__:# 创建线程池最多2个线程withThreadPoolExecutor(max_workers2)asexecutor:# 批量提交任务resultsexecutor.map(thread_task,[1,2,3])# 遍历结果forresinresults:print(res)关键点讲解ThreadPoolExecutor最推荐的多线程写法map(任务函数, 参数列表)一键批量提交自动管理线程不用start/join适合IO 密集型爬虫、文件、网络 终极总结线程共享数据 → 必须加锁进程独立数据 → 通信要用 Queue进程池通信 → 必须用 Manager ().QueueIO 密集 → 线程池CPU 密集 → 进程池Windows 多进程 → 必须加 if *name* “*main*” Author:zhuyahao Time:2026/4/17 Desc: # 0. 导入模块 importmultiprocessingimportthreadingfromconcurrent.futuresimportThreadPoolExecutor,ProcessPoolExecutorimporttimeimportos# 1. 多线程 互斥锁售票 ticket10lockthreading.Lock()defsale_ticket():globalticketwhileTrue:lock.acquire()# 加锁try:ifticket0:time.sleep(0.1)print(f{threading.current_thread().name}卖出第{ticket}张票)ticket-1else:print(f{threading.current_thread().name}票已卖完)breakfinally:lock.release()# 解锁# 2. 多进程独立任务 defprocess_task(name):print(f子进程{name}运行PID{os.getpid()})time.sleep(0.5)returnf进程{name}完成# 3. 进程池 Manager队列通信 defpool_task(q,i):q.put(f进程池任务{i}完成)time.sleep(0.3)# 4. 线程池 defthread_task(i):time.sleep(0.2)returnf线程池任务{i}完成# 主程序入口Windows必须 if__name____main__:print( 1. 多线程售票锁)t1threading.Thread(targetsale_ticket,name窗口1)t2threading.Thread(targetsale_ticket,name窗口2)t1.start()t2.start()t1.join()t2.join()print(\n 2. 多进程 )p1multiprocessing.Process(targetprocess_task,args(A,))p2multiprocessing.Process(targetprocess_task,args(B,))p1.start()p2.start()p1.join()p2.join()print(\n 3. 进程池 通信 )qmultiprocessing.Manager().Queue()withProcessPoolExecutor(2)aspool:foriinrange(10):pool.submit(pool_task,q,i)whilenotq.empty():print(q.get())print(\n 4. 线程池 )withThreadPoolExecutor(2)asexecutor:resultsexecutor.map(thread_task,[1,2,3])forresinresults:print(res)print(\n✅ 全部运行完成)1.多线程售票锁窗口1卖出第10张票 窗口2卖出第9张票 窗口2卖出第8张票 窗口2卖出第7张票 窗口2卖出第6张票 窗口2卖出第5张票 窗口2卖出第4张票 窗口2卖出第3张票 窗口1卖出第2张票 窗口2卖出第1张票 窗口1票已卖完 窗口2票已卖完2.多进程子进程 A 运行PID4400子进程 B 运行PID320363.进程池通信进程池任务0完成 进程池任务1完成 进程池任务2完成 进程池任务3完成 进程池任务4完成 进程池任务5完成 进程池任务6完成 进程池任务7完成 进程池任务8完成 进程池任务9完成4.线程池线程池任务1完成 线程池任务2完成 线程池任务3完成 ✅ 全部运行完成 进程已结束退出代码为0