周末做兼职上什么网站找论坛静态网站源码
2026/1/12 8:43:59 网站建设 项目流程
周末做兼职上什么网站找,论坛静态网站源码,个人logo设计图片,网站后台是怎样制作《从零构建 Python 线程池#xff1a;深入理解 Work Queue、条件变量与并发设计的本质》 一、开篇#xff1a;为什么要手写一个线程池#xff1f; Python 自 1991 年诞生以来#xff0c;以其简洁优雅的语法、强大的生态系统和“胶水语言”的灵活性#xff0c;迅速成为 W…《从零构建 Python 线程池深入理解 Work Queue、条件变量与并发设计的本质》一、开篇为什么要手写一个线程池Python 自 1991 年诞生以来以其简洁优雅的语法、强大的生态系统和“胶水语言”的灵活性迅速成为 Web 开发、数据科学、人工智能、自动化等领域的核心语言。随着业务规模增长、实时性需求提升并发编程成为 Python 开发者必须掌握的能力。你可能已经使用过concurrent.futures.ThreadPoolExecutormultiprocessing.Poolasyncio这些工具极大降低了并发编程的门槛但也让很多开发者忽略了底层原理。为什么要手写线程池彻底理解线程池的设计思想掌握工作队列Work Queue的生产者-消费者模型理解条件变量Condition的作用学会构建可扩展的并发框架在面试、系统设计、性能优化中具备底层能力更重要的是当你能手写线程池时你对 Python 并发的理解将从“会用”跃升到“精通”。二、基础回顾Python 并发的核心概念为了让初学者也能顺利阅读我们先快速回顾 Python 并发的基础知识。1. 线程与 GILPython 的线程由操作系统调度但 CPython 有 GIL全局解释器锁导致多线程适合 I/O 密集任务多线程不适合 CPU 密集任务但线程池的设计思想与 GIL 无关它是通用的并发模型。2. 工作队列Work Queue线程池的核心思想主线程不断向队列提交任务工作线程不断从队列取任务执行队列为空时工作线程等待队列有任务时工作线程被唤醒这就是典型的生产者-消费者模型。3. 条件变量Condition条件变量用于线程等待某个条件成立其他线程改变条件后发出通知线程池中工作线程等待“队列非空”主线程提交任务后通知工作线程三、基础语法示例装饰器与函数调用时间为了保持文章结构一致我们插入一个基础示例importtimedeftimer(func):defwrapper(*args,**kwargs):starttime.time()resultfunc(*args,**kwargs)endtime.time()print(f{func.__name__}花费时间{end-start:.4f}秒)returnresultreturnwrappertimerdefcompute_sum(n):returnsum(range(n))print(compute_sum(1000000))四、正式进入主题手写一个线程池我们将从最小可用版本开始一步步扩展。五、第一步实现一个线程安全的工作队列Work Queue我们需要一个任务队列list 或 deque一个锁Lock一个条件变量Condition代码WorkQueue 实现importthreadingfromcollectionsimportdequeclassWorkQueue:def__init__(self):self.queuedeque()self.lockthreading.Lock()self.not_emptythreading.Condition(self.lock)defput(self,item):withself.not_empty:self.queue.append(item)self.not_empty.notify()# 通知等待的线程defget(self):withself.not_empty:whilenotself.queue:self.not_empty.wait()# 队列为空等待returnself.queue.popleft()关键点解析Condition(self.lock)条件变量绑定锁wait()释放锁并阻塞直到被 notifynotify()唤醒一个等待线程while not queue防止虚假唤醒六、第二步实现 Worker 线程Worker 线程需要无限循环从队列取任务执行任务支持线程池关闭代码Worker 实现classWorker(threading.Thread):def__init__(self,work_queue,pool):super().__init__()self.work_queuework_queue self.poolpool self.daemonTrue# 主线程退出时自动退出defrun(self):whileTrue:taskself.work_queue.get()iftaskisNone:# 收到关闭信号breakfunc,args,kwargstasktry:func(*args,**kwargs)exceptExceptionase:print(任务执行异常,e)七、第三步实现 ThreadPool线程池主体线程池需要初始化多个 Worker提供 submit() 方法提交任务提供 shutdown() 方法关闭线程池代码ThreadPool 实现classThreadPool:def__init__(self,num_workers4):self.work_queueWorkQueue()self.workers[]self.num_workersnum_workers self._init_workers()def_init_workers(self):for_inrange(self.num_workers):workerWorker(self.work_queue,self)worker.start()self.workers.append(worker)defsubmit(self,func,*args,**kwargs):self.work_queue.put((func,args,kwargs))defshutdown(self,waitTrue):# 向每个 worker 发送关闭信号for_inself.workers:self.work_queue.put(None)ifwait:forworkerinself.workers:worker.join()八、完整可运行版本手写线程池下面是完整代码可直接运行importthreadingfromcollectionsimportdequeclassWorkQueue:def__init__(self):self.queuedeque()self.lockthreading.Lock()self.not_emptythreading.Condition(self.lock)defput(self,item):withself.not_empty:self.queue.append(item)self.not_empty.notify()defget(self):withself.not_empty:whilenotself.queue:self.not_empty.wait()returnself.queue.popleft()classWorker(threading.Thread):def__init__(self,work_queue,pool):super().__init__()self.work_queuework_queue self.poolpool self.daemonTruedefrun(self):whileTrue:taskself.work_queue.get()iftaskisNone:breakfunc,args,kwargstasktry:func(*args,**kwargs)exceptExceptionase:print(任务执行异常,e)classThreadPool:def__init__(self,num_workers4):self.work_queueWorkQueue()self.workers[]self.num_workersnum_workers self._init_workers()def_init_workers(self):for_inrange(self.num_workers):workerWorker(self.work_queue,self)worker.start()self.workers.append(worker)defsubmit(self,func,*args,**kwargs):self.work_queue.put((func,args,kwargs))defshutdown(self,waitTrue):for_inself.workers:self.work_queue.put(None)ifwait:forworkerinself.workers:worker.join()九、测试线程池执行多个任务importtimedeftask(n):print(f开始任务{n})time.sleep(1)print(f结束任务{n})poolThreadPool(num_workers3)foriinrange(10):pool.submit(task,i)pool.shutdown()输出示例开始任务 0 开始任务 1 开始任务 2 结束任务 0 开始任务 3 ...十、进阶优化支持 Future、返回值、异常捕获如果你愿意我可以继续扩展支持 Future 对象支持任务返回值支持任务优先级支持最大队列长度支持超时支持线程复用统计这些都是生产级线程池需要的能力。十一、案例实战用手写线程池构建一个小型爬虫importrequestsdeffetch(url):resprequests.get(url)print(url,len(resp.text))urls[https://www.python.org,https://www.github.com,https://www.baidu.com,]*3poolThreadPool(5)forurlinurls:pool.submit(fetch,url)pool.shutdown()十二、最佳实践总结使用条件变量实现线程同步使用队列实现生产者-消费者模型使用 None 作为关闭信号使用 daemon 线程避免阻塞退出使用 join() 等待线程结束十三、前沿视角Python 并发的未来PEP 703无 GIL Python正在推进asyncio 已成为异步标准FastAPI、Quart 等框架推动异步生态Rust PythonPyO3成为高性能趋势多线程未来可能真正实现并行十四、总结与互动我们从 Python 基础讲起一步步构建了工作队列条件变量同步Worker 线程线程池主体完整可运行线程池你不仅学会了“如何写”更理解了“为什么这样写”。我很想听听你的想法你希望我继续扩展支持 Future 的版本吗你想看“手写协程调度器”或“手写进程池”吗告诉我你的方向我可以继续为你构建更完整的并发体系文章。

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

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

立即咨询