如何直观地通过代码例子来证明Python的GIL存在

首页 / 常见问题 / 低代码开发 / 如何直观地通过代码例子来证明Python的GIL存在
作者:开发工具 发布时间:10-22 16:47 浏览量:9414
logo
织信企业级低代码开发平台
提供表单、流程、仪表盘、API等功能,非IT用户可通过设计表单来收集数据,设计流程来进行业务协作,使用仪表盘来进行数据分析与展示,IT用户可通过API集成第三方系统平台数据。
免费试用

Python的全局解释器锁(Global Interpreter Lock,简称GIL)是实现在多线程环境中单线程执行字节码的机制,它确保任何时刻只有一个线程可以执行Python字节码。这一设计的初衷在于简化内存管理并减少引入多线程时可能发生的并发错误。然而,GIL也因降低多核处理器上的多线程程序效率而备受诟病。在多线程密集型计算任务中,这一限制就变得尤为明显,因为多个线程无法充分利用多核处理器的优势。

为了得到直观的证明,我们可以通过两个例子来观察GIL的影响:一个是CPU密集型任务,一个是I/O密集型任务。CPU密集型任务会因为GIL的存在而不能有效地利用多线程提高性能,而在I/O密集型任务中,由于线程大部分时间在等待外部资源,GIL释放会比较频繁,多线程仍能有效提高性能。

一、 CPU密集型任务例子

在这个例子中,我们将创建多个线程分别执行累加操作,累加操作是纯CPU密集型任务,几乎没有I/O操作。

import time

import threading

一个简单的累加函数

def count(n):

while n > 0:

n -= 1

单线程执行

start_time = time.time()

count(100000000)

end_time = time.time()

print(f"单线程执行时间: {end_time - start_time}")

多线程执行

start_time = time.time()

t1 = threading.Thread(target=count,args=(50000000,))

t2 = threading.Thread(target=count,args=(50000000,))

t1.start()

t2.start()

t1.join()

t2.join()

end_time = time.time()

print(f"两个线程执行时间: {end_time - start_time}")

这段代码中,我们首先单线程执行count函数,然后再使用两个线程各自执行一半数量的count,按理说,在有多个核的系统上,两个线程的执行时间应当大约是单线程的一半,然而由于GIL的存在,我们会观察到两个线程执行的时间并不会比单线程快很多,有时甚至更慢。

二、 I/O密集型任务例子

接下来,我们用一个I/O密集型任务的例子来观察GIL的影响。

import time

import threading

import requests

一个简单的下载网页内容的函数

def download(url):

response = requests.get(url)

return response.text

单线程执行

start_time = time.time()

website_list = [

'http://www.jython.org',

'http://olympus.realpython.org/dice',

] * 10

for website in website_list:

download(website)

end_time = time.time()

print(f"单线程执行时间: {end_time - start_time}")

多线程执行

start_time = time.time()

threads = []

for website in website_list:

thread = threading.Thread(target=download, args=(website,))

thread.start()

threads.append(thread)

for thread in threads:

thread.join()

end_time = time.time()

print(f"多线程执行时间: {end_time - start_time}")

在这段代码中,我们同样先用单线程下载多个网页,然后使用多线程方式。与CPU密集型任务不同的是,下载网页时大部分时间都在等待网络响应,因此GIL对性能的影响不会那么显著。从输出结果我们可以看出,多线程在I/O密集型任务中能明显减少执行时间。

三、 GIL带来的效率问题

在多线程工作的情况下,由于GIL的存在,即使是运行在多核CPU上,Python 的多线程程序也无法充分利用多核处理器的优势。当线程尝试执行时,GIL确保只有一个线程可以进入解释器。如果有多个线程竞争执行资源,程序必须在线程间进行上下文切换,导致额外的开销。

四、 GIL相关的改善措施

尽管GIL带来一些并发性能问题,但是也有多种方法可以在不同程度上缓解这一问题:

  • 使用多进程代替多线程multiprocessing库可以创建多个进程,每个进程都有自己的Python解释器和内存空间,因此不受GIL的限制。

  • 利用支持原生线程的扩展:一些Python扩展,例如numpy,能够在执行密集型数学操作时释放GIL。

  • 使用Jython或IronPython:这些Python实现没有GIL,可以在多线程环境下更好地执行。

  • 使用异步编程:通过使用asyncio库和异步编程模式,我们可以在单线程内执行并发操作,适合解决I/O密集型任务。

总结,Python的GIL是个复杂的话题,它既是历史遗留问题也是设计折衷的结果。不过,GIL并非不可逾越的障碍,通过设计和实现上的选择,可以在有限程度上规避它带来的影响。

相关问答FAQs:

1. 为什么Python的GIL会影响多线程性能?
Python的GIL是全局解释器锁,它在同一时间只允许一个线程执行Python字节码。这意味着在CPU密集型任务中,无论多少个线程被创建,实际上只有一个线程在执行代码,因此无法充分利用多核处理器的优势。

2. GIL对IO密集型任务有何影响?
对于IO密集型任务(如网络请求、文件操作等),由于线程在执行IO操作时会释放GIL,其他线程便可以获得执行权。因此,在这种情况下,多线程可以提供较好的性能提升。

3. 如何通过代码例子来证明Python的GIL存在?
假设我们有一个计数器(counter)变量,然后创建两个线程,分别对该变量进行递增操作,并分别执行10000次。如果Python的GIL不存在,我们期望最终的计数值应该是20000。但是在实际执行过程中,由于GIL的存在,多线程执行时会相互竞争GIL,导致实际的计数值小于20000。这个例子可以通过观察最终计数值来证明Python的GIL存在。

最后建议,企业在引入信息化系统初期,切记要合理有效地运用好工具,这样一来不仅可以让公司业务高效地运行,还能最大程度保证团队目标的达成。同时还能大幅缩短系统开发和部署的时间成本。特别是有特定需求功能需要定制化的企业,可以采用我们公司自研的企业级低代码平台织信Informat。 织信平台基于数据模型优先的设计理念,提供大量标准化的组件,内置AI助手、组件设计器、自动化(图形化编程)、脚本、工作流引擎(BPMN2.0)、自定义API、表单设计器、权限、仪表盘等功能,能帮助企业构建高度复杂核心的数字化系统。如ERP、MES、CRM、PLM、SCM、WMS、项目管理、流程管理等多个应用场景,全面助力企业落地国产化/信息化/数字化转型战略目标。 版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们微信:Informat_5 处理,核实后本网站将在24小时内删除。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系邮箱:hopper@cornerstone365.cn 处理,核实后本网站将在24小时内删除。

最近更新

什么是外向潜在客户开发
10-30 10:47
产品开发过程的阶段有哪些
10-30 10:47
网站开发图标怎么设置
10-30 10:47
如何组建it开发团队
10-30 10:47
开发商团队视频怎么拍好看
10-30 10:47
公司用什么系统开发的
10-30 10:47
系统开发选什么专业好呢
10-30 10:47
什么为嵌入式系统开发
10-30 10:47
系统开发完成后移交什么
10-30 10:47

立即开启你的数字化管理

用心为每一位用户提供专业的数字化解决方案及业务咨询

  • 深圳市基石协作科技有限公司
  • 地址:深圳市南山区科技中一路大族激光科技中心909室
  • 座机:400-185-5850
  • 手机:137-1379-6908
  • 邮箱:sales@cornerstone365.cn
  • 微信公众号二维码

© copyright 2019-2024. 织信INFORMAT 深圳市基石协作科技有限公司 版权所有 | 粤ICP备15078182号

前往Gitee仓库
微信公众号二维码
咨询织信数字化顾问获取最新资料
数字化咨询热线
400-185-5850
申请预约演示
立即与行业专家交流