怎么在网站上做图片轮播公司展厅装修
2026/3/9 13:43:52 网站建设 项目流程
怎么在网站上做图片轮播,公司展厅装修,app开发公司哪,怎样看网站是什么语言做的Python 多线程详解#xff1a;threading 模块从入门到高级实例#xff08;2026 年视角#xff09; Python 的 threading 模块 是标准库中实现多线程编程的核心工具。它基于线程模型#xff0c;让你能并发执行多个任务#xff0c;尤其适合 I/O 密集型场景#xff08;如网…Python 多线程详解threading 模块从入门到高级实例2026 年视角Python 的threading 模块是标准库中实现多线程编程的核心工具。它基于线程模型让你能并发执行多个任务尤其适合 I/O 密集型场景如网络请求、文件读写。但 Python 有GILGlobal Interpreter Lock全局解释器锁所以在 CPU 密集型任务中多线程并不能真正并行更适合多进程 multiprocessing。2026 年随着 Python 3.13 的 GIL 优化可选无 GIL 模式多线程性能有显著提升但默认仍需注意。本教程从基础到高级逐步讲解 超详细代码实例每个实例附运行说明 潜在问题 优化建议。假设你用 Python 3.8代码可在 Jupyter 或 VS Code 中运行。每个实例都独立可复制粘贴测试。1. 多线程基础概念线程 vs 进程线程是进程内的执行单元共享内存更快启动但需小心数据竞争。进程独立内存更安全但开销大。threading 模块关键类/函数类/函数描述常见用法Thread(targetfunc, args())创建线程对象启动子线程执行 functhread.start()启动线程—thread.join()等待线程结束主线程阻塞等子线程threading.Lock()互斥锁防止数据竞争with lock: …threading.RLock()可重入锁同一线程可多次获取递归函数中用threading.Semaphore(n)信号量限流控制同时访问资源的线程数threading.Condition()条件变量线程间通信生产者-消费者模式threading.Event()事件信号灯一个线程通知多个线程queue.Queue()线程安全队列数据共享多线程间传递数据threading.current_thread()获取当前线程打印线程名/ID注意多线程不适合 CPU 密集如计算密集循环用 multiprocessing 或 concurrent.futures.ThreadPoolExecutor更高层抽象。2. 入门实例简单多线程场景主线程 子线程并发打印消息演示线程创建/启动/等待。importthreadingimporttimedefworker(name):print(f线程{name}开始执行...)time.sleep(2)# 模拟耗时任务print(f线程{name}执行结束)# 创建线程t1threading.Thread(targetworker,args(子线程1,))t2threading.Thread(targetworker,args(子线程2,))# 启动线程t1.start()t2.start()print(主线程继续执行...)# 等待子线程结束可选如果不 join主线程可能先结束t1.join()t2.join()print(所有线程结束主线程退出。)运行输出大致顺序非严格线程 子线程1 开始执行... 线程 子线程2 开始执行... 主线程继续执行... 线程 子线程1 执行结束 线程 子线程2 执行结束 所有线程结束主线程退出。详解targetworker指定线程执行的函数。args(子线程1,)传参必须是元组。start()启动线程立即返回非阻塞。join()阻塞主线程直到该线程结束。潜在问题无共享数据无需锁。但如果函数有异常会静默失败用 try-except 捕获。优化用daemonTrue设置守护线程主线程结束时自动杀子线程。3. 中级实例线程间数据共享 锁避免竞争场景多个线程修改共享变量计数器无锁 vs 有锁对比。演示数据竞争问题。importthreading counter0# 共享变量defincrement(n):globalcounterfor_inrange(n):counter1# 非原子操作可能竞争# 无锁版本会出错threads[]for_inrange(10):tthreading.Thread(targetincrement,args(100_000,))threads.append(t)t.start()fortinthreads:t.join()print(无锁结果预期 1,000,000:,counter)# 实际 ~900,000丢失计数# 有锁版本counter0lockthreading.Lock()defincrement_locked(n):globalcounterfor_inrange(n):withlock:# 获取锁独占执行counter1threads[]for_inrange(10):tthreading.Thread(targetincrement_locked,args(100_000,))threads.append(t)t.start()fortinthreads:t.join()print(有锁结果预期 1,000,000:,counter)# 正确 1,000,000详解数据竞争GIL 虽保护解释器但counter 1是多步操作读-改-写线程切换时丢失。Lock()互斥锁with lock:自动获取/释放。潜在问题死锁两个线程互等锁性能瓶颈锁粒度太大。优化用 RLock() 如果函数递归调用锁最小化锁内代码。4. 高级实例生产者-消费者模式Condition Queue场景生产者线程生成数据消费者线程处理。演示线程通信 队列安全共享。importthreadingimportqueueimporttimeimportrandom qqueue.Queue(maxsize5)# 线程安全队列限 5 项defproducer():foriinrange(10):itemrandom.randint(1,100)q.put(item)# 阻塞如果队列满print(f生产者生产:{item}(队列大小:{q.qsize()}))time.sleep(random.uniform(0.5,1.5))q.put(None)# 结束信号defconsumer(name):whileTrue:itemq.get()# 阻塞如果队列空ifitemisNone:print(f{name}收到结束信号)breakprint(f{name}消费:{item}(队列大小:{q.qsize()}))time.sleep(random.uniform(1,2))# 启动pthreading.Thread(targetproducer)c1threading.Thread(targetconsumer,args(消费者1,))c2threading.Thread(targetconsumer,args(消费者2,))p.start()c1.start()c2.start()p.join()c1.join()c2.join()print(生产消费结束)运行输出示例生产者生产: 42 (队列大小: 1) 消费者1 消费: 42 (队列大小: 0) 生产者生产: 73 (队列大小: 1) 消费者2 消费: 73 (队列大小: 0) ... (继续直到 10 项) 消费者1 收到结束信号 消费者2 收到结束信号 生产消费结束详解Queue()线程安全 FIFO先入先出。put()/get()自动处理锁。None作为哨兵通知消费者结束多消费者时需多个哨兵或用 Event。潜在问题队列满/空时阻塞如果生产慢消费快可能饥饿。优化用queue.PriorityQueue()优先级队列或 LifoQueue 栈式。5. 高级实例限流 信号量Semaphore场景模拟数据库连接池限制同时访问的线程数e.g., 最多 3 个。importthreadingimporttime semthreading.Semaphore(3)# 最多 3 个线程同时访问defaccess_db(name):print(f{name}尝试访问 DB...)withsem:# 获取信号量计数 -1如果 0 则阻塞print(f{name}访问 DB 中...)time.sleep(2)# 模拟查询print(f{name}访问结束)threads[]foriinrange(10):tthreading.Thread(targetaccess_db,args(f线程{i},))threads.append(t)t.start()time.sleep(0.2)# 错开启动fortinthreads:t.join()运行输出示例线程0 尝试访问 DB... 线程0 访问 DB 中... 线程1 尝试访问 DB... 线程1 访问 DB 中... 线程2 尝试访问 DB... 线程2 访问 DB 中... 线程3 尝试访问 DB... # 阻塞直到前一个释放 ...详解Semaphore(n)计数器初始 n。acquire()减 10 时阻塞release()加 1。with sem:自动 acquire/release。潜在问题忘记 release() 导致死锁n 太小瓶颈大。优化结合 Lock 保护共享资源2026 年用 asyncio.Semaphore 异步版。6. 高级实例线程间通信Condition Event场景一个线程等待另一个线程的信号e.g., 下载完成通知处理。importthreadingimporttime condthreading.Condition()# 条件变量eventthreading.Event()# 事件信号defdownloader():print(下载开始...)time.sleep(3)withcond:print(下载完成通知等待者...)cond.notify_all()# 通知所有等待线程event.set()# 设置事件为 Truedefprocessor(name):print(f{name}等待下载完成...)withcond:cond.wait()# 阻塞直到 notifyprint(f{name}收到通知开始处理...)# 启动dthreading.Thread(targetdownloader)p1threading.Thread(targetprocessor,args(处理器1,))p2threading.Thread(targetprocessor,args(处理器2,))d.start()p1.start()p2.start()# 用 Event 额外等待event.wait()# 主线程等待事件print(所有处理完成)p1.join()p2.join()d.join()运行输出处理器1 等待下载完成... 处理器2 等待下载完成... 下载开始... 下载完成通知等待者... 处理器1 收到通知开始处理... 处理器2 收到通知开始处理... 所有处理完成详解Condition()结合锁用于 wait() / notify() / notify_all()。Event()简单信号set() 后 is_set() 为 True所有 wait() 唤醒。潜在问题Condition 需在 with cond 内使用Event 一旦 set 不可 reset用 clear()。优化Condition 适合复杂同步Event 适合简单通知。7. 常见问题 最佳实践2026 年视角GIL 影响I/O 任务如 API 调用用多线程好CPU 任务用 multiprocessing 或 concurrent.futures.ProcessPoolExecutor。线程安全全局变量用锁列表/字典用 queue 或 threading.local()线程本地存储。调试用threading.enumerate()列所有线程threading.settrace()追踪。性能监控用 timeit / cProfile 测速psutil 查 CPU/内存。高级替代asyncio异步 I/O更高效concurrent.futures线程/进程池简化管理。陷阱不要在子线程改主线程 GUIe.g., Tkinter异常传播需手动处理。做完这些实例你基本掌握 threading 了推荐实践写一个多线程下载器requests ThreadPoolExecutor。你现在最想深入哪个部分e.g., 更多队列例子asyncio 对比或者贴你的代码我帮 debug

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询