掘金 人工智能 前天 09:58
Python多线程全面解析,从使用到GIL的底层逻辑
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文深入探讨了Python中的多线程和多进程并发编程,旨在帮助开发者解决现实场景中的并发问题,例如爬虫的并发请求和GUI程序的界面卡顿。文章首先介绍了Python多线程的基础知识,包括线程的创建、生命周期管理、守护线程以及线程同步。随后,文章对比了多线程与多进程的优劣,并强调了在不同场景下选择合适的并发方案的重要性,例如在CPU密集型任务中使用多进程,而在I/O密集型任务中使用多线程。通过示例代码,读者可以更好地理解和应用这些并发技术。

💡 **线程创建与管理:** Python提供了两种创建线程的方式:直接传入目标函数和继承Thread类。线程的生命周期管理涉及start()和join()方法,其中join()用于等待线程完成。守护线程(daemon thread)可以在主线程退出时自动终止。

🔒 **线程同步原语:** Python提供了多种线程同步原语,如Lock锁、RLock可重入锁、Semaphore信号量和Condition条件变量。Lock锁用于保护共享资源,RLock适用于递归场景,Semaphore控制并发访问资源的线程数量,Condition用于线程间通信和协调。

📦 **线程间通信:** 线程间可以通过共享变量和Queue队列进行数据交换。使用queue.Queue()是线程安全的方式,生产者线程使用put()方法将数据放入队列,消费者线程使用get()方法从队列中获取数据。Queue的task_done()和join()方法用于确保所有任务被处理完毕。

问题:

Python多线程编程基础:快速上手

def worker(task_id):    print(f"Processing task {task_id}")thread = Thread(target=worker, args=(1,))from threading import Threadclass MyThread(Thread):    def run(self):        print(f"Thread {self.name} is running")thread = MyThread()thread.start()  # 启动线程而非直接调用run()
threads = [Thread(target=worker, args=(i,)) for i in range(5)]for t in threads: t.start()for t in threads: t.join()  # 等待所有线程完成
t = Thread(target=background_task, daemon=True)t.start()  # 主线程退出时自动终止

线程同步

当多个线程对共享资源进行操作时,可能会引发数据不一致的问题,这时就需要进行线程同步。Python提供了多种同步原语:

import threadingcounter = 0lock = threading.Lock()def increment():    global counter    for _ in range(100000):        lock.acquire()  # 获取锁        try:            counter += 1        finally:            lock.release()  # 释放锁# 创建并启动线程threads = [threading.Thread(target=increment) for _ in range(2)]for t in threads:    t.start()for t in threads:    t.join()print(f'最终结果: {counter}')  # 结果应为200000
semaphore = threading.Semaphore(3)  # 最多允许3个线程同时访问def worker():    with semaphore:  # 获取信号量        print('正在访问资源...')
condition = threading.Condition()def consumer():    with condition:        condition.wait()  # 等待通知        print('收到通知,开始消费')def producer():    with condition:        print('生产完成,发送通知')        condition.notify()  # 发送通知

线程间通信Queue vs 共享变量

线程间可以通过共享变量和队列Queue来交换数据,使用queue.Queue()是线程安全的方式

from queue import Queueimport threadingdef producer(queue):    for item in range(5):        queue.put(item)        print(f'生产: {item}')def consumer(queue):    while True:        item = queue.get()        print(f'消费: {item}')        queue.task_done()  # 通知队列任务已完成q = Queue()t1 = threading.Thread(target=producer, args=(q,))t2 = threading.Thread(target=consumer, args=(q,), daemon=True)  # 守护线程t1.start()t2.start()t1.join()  # 等待生产者线程完成q.join()   # 等待队列中的所有任务被处理完

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

Python 多线程 多进程 并发编程
相关文章