Python 线程和进程和协程总结

本文详细介绍了Python中的线程、进程及协程的概念与区别,并探讨了多线程与多进程的应用场景,特别是针对GIL(全局解释器锁)的影响进行了深入分析。

Python 线程和进程和协程总结

线程和进程和协程

进程

  • 进程是程序执行时的一个实例,是担当分配系统资源(CPU时间、内存等)的基本单位;

  • 进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响;

  • 进程间可以通过信号、信号量、共享内存、管道、队列等来进行通信;

  • 进程创建、销毁、上下文切换带来的开销成本都很大;

线程

  • 线程是进程的一个实体,作为独立运行和独立调度的基本单位。

  • 线程可与同属一个进程的其他的线程共享进程所拥有的全部资源。

  • 线程只是一个进程中的不同执行路径,没有单独的地址空间,一个线程死掉就会导致整个进程死掉。

  • 线程创建、销毁、上下文切换带来的开销要比进程小得多;

协程

  • 协程的控制有应用程序控制,非抢占式的;

  • 切换快,开销相较线程更小,所以可以开更多的协程;

具体使用参考Python 协程总结

多线程和多进程

多线程

优点
  1. 它是一种非常"节俭"的多任务操作方式。我们知道,在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这是一种"昂贵"的多任务工作方式。而运行于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而且,线程间彼此切换所需的时间也远远小于进程间切换所需要的时间。

  2. 线程间方便的通信机制,对不同进程来说,它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行,这种方式不仅费时,而且很不方便。线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其它线程所用。

  3. 提高应用程序响应。这对图形界面的程序尤其有意义,当一个操作耗时很长时,整个系统都会等待这个操作,此时程序不会响应键盘、鼠标、菜单的操作,而使用多线程技术,将耗时长的操作(time consuming)置于一个新的线程,可以避免这种尴尬的情况。

  4. 使多CPU系统更加有效。操作系统会保证当前线程数不大于CPU数目时,不同的线程运行于不同的CPU上。

GIL

全局解释器锁是在实现Python解析器(CPython)时所引入的一个概念。每个线程在执行的过程都需要先获取GIL,保证同一时刻只有一个线程可以执行代码。

Q&A: 为什么说GIL对于CPU密集型任务不友好,而对于IO密集型任务比较友好呢?

这是因为GIL的释放逻辑是当前线程遇见IO操作或者ticks计数达到100(ticks可以看作是python自身的一个计数器,专门做用于GIL,每次释放后归零,这个计数可以通过 sys.setcheckinterval 来调整),进行释放。而每次释放GIL锁,线程进行锁竞争、切换线程,会消耗资源。

那CPU密集型任务(各种循环处理、计数等等),在这种情况下,ticks计数很快就会达到阈值,然后触发GIL的释放与再竞争(多个线程来回切换当然是需要消耗资源的),但是对于IO密集型任务,多线程能够有效提升效率(单线程下有IO操作会进行IO等待,造成不必要的时间浪费,而开启多线程能在线程A等待时,自动切换到线程B,可以不浪费CPU的资源,从而能提升程序执行效率)。因此说GIL对于CPU密集型任务不友好,而对于IO密集型任务比较友好。

解决方案

multiprocessing库的出现很大程度上是为了弥补thread库因为GIL而低效的缺陷,它完整的复制了一套thread所提供的接口方便迁移。唯一的不同就是它使用了多进程而不是多线程。每个进程有自己的独立的GIL,因此也不会出现进程之间的GIL争抢。当然multiprocessing也不是万能良药。它的引入会增加程序实现时线程间数据通讯和同步的困难。Python的多线程在多核CPU上,只对于IO密集型计算产生正面效果;而当至少有一个CPU密集型线程存在时,那么多线程效率会由于GIL而大幅下降,这个时候就得使用多进程;

多进程

Python中的多线程因为GIL的关系并不算是真正的多线程,如果想要充分地使用多核CPU的资源,大部分情况需要使用多进程。multiprocessing支持子进程、通信和共享数据、执行不同形式的同步,提供了Process、Queue、Pipe、Lock等组件。

谈谈python的GIL、多线程、多进程

转载于:https://www.cnblogs.com/George1994/p/10615435.html

<think>我们正在回答用户关于Python线程进程协程的区别与用法的问题。根据系统级指令,需要:1.使用$...$格式的行内数学表达式(但本问题可能较少涉及数学表达式,若有则需注意)2.独立公式使用$$...$$格式并单独成段(同样,本问题可能较少涉及)3.LaTeX语法正确4.使用中文回答5.生成相关问题6.回答中引用的段落末尾自然地添加引用标识用户的问题:我想了解Python线程进程协程的概念及使用方法请问Python线程进程协程区别与用法我们参考了用户提供的引用[1]、[2]、[3],其中:引用[1]提到Python的GIL(全局解释器锁)导致同一时刻只有一个线程运行,目的是确保线程安全。引用[2]展示了Python线程的创建守护线程的设置,以及线程间的执行顺序。引用[3]简单介绍了协程的概念。但是,用户的需求是了解线程进程协程的概念、区别以及使用方法。因此,我们将按以下结构组织回答:1.进程(Process)的概念用法2.线程(Thread)的概念用法(包括GIL的影响)3.协程(Coroutine)的概念用法4.三者的区别应用场景5.代码示例(包括进程线程协程的创建)注意:在回答中,如果引用到用户提供的引用内容,需要在末尾添加引用标识[^1]、[^2]、[^3]。由于引用内容已经给出,但我们在回答中也需要引用一些常识性的知识,但要求引用标识只对用户提供的引用进行标注,所以:在提到GIL时,我们可以引用[^1];在提到线程守护线程执行顺序时引用[^2];在提到协程的概念时引用[^3]。但是,请注意,用户提供的引用[^3]内容较少,我们可能还需要补充其他来源的知识(但用户没有提供其他引用,因此我们主要依靠自己的知识库,并在必要时引用这些已有的引用)。由于要求生成相关问题,在回答最后需要添加“§§相关问题§§”部分。开始编写回答:</think> ### Python 线程进程协程:概念、区别与用法详解 #### 1. **进程 (Process)** - **概念**:操作系统资源分配的基本单位,拥有独立的内存空间(如 Python 中每个进程有独立的 GIL 解释器)。 - **用法**:适用于 CPU 密集型任务(如科学计算),通过 `multiprocessing` 模块实现: ```python from multiprocessing import Process def task(): print("进程执行中") if __name__ == '__main__': p = Process(target=task) p.start() # 启动子进程 p.join() # 等待子进程结束 ``` - **优点**:隔离性强,避免内存冲突;可充分利用多核 CPU。 - **缺点**:创建切换开销大,进程间通信(IPC)复杂(需队列、管道等)。 #### 2. **线程 (Thread)** - **概念**:进程内的执行单元,共享同一进程的内存空间,但受 **GIL(全局解释器锁)** 限制。 - **GIL 影响**:无论多少 CPU 核心,Python 线程同一时刻仅一个线程运行(确保数据安全)[^1]。 - **用法**:适用于 I/O 密集型任务(如网络请求),通过 `threading` 模块实现: ```python import threading def task(): print("线程执行中") thread = threading.Thread(target=task) thread.start() # 启动线程 thread.join() # 等待结束 ``` **守护线程**:主线程结束则自动终止(`daemon=True`)[^2]。 - **优点**:轻量级,切换开销小;共享数据方便(需加锁避免竞态条件)。 - **缺点**:GIL 限制多核性能;需处理线程同步问题(如死锁)。 #### 3. **协程 (Coroutine)** - **概念**:用户级轻量级线程,通过协作式调度而非抢占式调度,在单线程内实现并发[^3]。 - **用法**:Python 3.5+ 通过 `asyncio` `async/await` 实现: ```python import asyncio async def task(): print("协程开始") await asyncio.sleep(1) # 非阻塞 I/O 操作 print("协程结束") asyncio.run(task()) # 执行协程 ``` - **优点**:无锁、无 GIL 限制;资源开销极小(可同时启用数万个协程);适合高并发 I/O。 - **缺点**:无法利用多核;需配合异步库(如 `aiohttp`)使用。 --- ### **三者的核心区别** | 特性 | 进程 | 线程 | 协程 | |-------------|-------------------------|-------------------------|-------------------------| | **隔离性** | 高(独立内存) | 低(共享内存) | 无(共享线程资源) | | **开销** | 高(创建/切换慢) | 中等 | 极低(无内核切换) | | **并发性** | 多核并行 | 伪并行(受 GIL 限制) | 单线程并发 | | **适用场景**| CPU 密集型任务 | I/O 密集型任务 | 超高并发 I/O 任务 | | **数据共享**| 需 IPC(队列、管道等) | 需同步机制(锁、信号量)| 无需同步(异步调度) | --- ### **使用场景总结** 1. **进程**:处理图像渲染、数值计算等 CPU 重负载任务(需并行计算)。 2. **线程**:文件读写、网络请求等 I/O 等待场景(GIL 在 I/O 时释放)[^1]。 3. **协程**:Web 服务器(如每秒处理数万请求)、爬虫并发(`asyncio` + `aiohttp`)。 > **关键点**:Python线程虽受 GIL 限制,但在 I/O 等待期间释放锁,允许其他线程运行,因此仍能加速 I/O 密集型任务[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值