当前位置: 首页 > news >正文

全局解释器锁 GIL

问题

你已经听说过全局解释器锁 GIL,担心它会影响到多线程程序的执行性能。

解决方案

尽管 Python 完全支持多线程编程,但是解释器的 C 语言实现部分在完全并行执行时并不是线程安全的。

实际上,解释器被一个全局解释器锁保护着,它确保任何时候 都只有一个 Python 线程执行。

GIL 最大的问题就是 Python 的多线程程序并不能利用 多核 CPU 的优势(比如一个使用了多个线程的计算密集型程序只会在一个单 CPU 上 面运行)。

在讨论普通的 GIL 之前,有一点要强调的是 GIL 只会影响到那些严重依赖 CPU 的程序(比如计算型的)。

如果你的程序大部分只会涉及到 I/O,比如网络交互,那么 使用多线程就很合适,因为它们大部分时间都在等待。

实际上,你完全可以放心的创建 几千个 Python 线程,现代操作系统运行这么多线程没有任何压力,没啥可担心的。

而对于依赖 CPU 的程序,你需要弄清楚执行计算的特点。

例如,优化底层算法 要比使用多线程运行快得多。类似的,由于 Python 是解释执行的,如果你将那些性能 瓶颈代码移到一个 C 语言扩展模块中,速度也会提升的很快。

如果你要操作数组,那 么使用 NumPy 这样的扩展会非常的高效。

还有一点要注意的是,线程不是专门用来优化性能的。一个 CPU 依赖型程序可能 会使用线程来管理一个图形用户界面、一个网络连接或其他服务。这时候,GIL 会产生 一些问题,因为如果一个线程长期持有 GIL 的话会导致其他非 CPU 型线程一直等待。

事实上,一个写的不好的 C 语言扩展会导致这个问题更加严重,尽管代码的计算部分 会比之前运行的更快些。

说了这么多,现在想说的是我们有两种策略来解决 GIL 的缺点。

首先,如果你完 全工作于 Python 环境中,你可以使用 multiprocessing 模块来创建一个进程池,并像协同处理器一样的使用。

例如,你有如下的线程代码:

#执行大型计算(CPU限制)

def some_work(args):
...return result

调用上述函数的线程

def some_thread():while True:...r = some_work(args)...修改代码,使用进程池:
pool = None
#执行大型计算(CPU限制)
def some_work(args):return result

调用上述函数的线程

def some_thread():while True:r = pool.apply(some_work, (args))

线程池

if __name__ == '__main__':import multiprocessingpool = multiprocessing.Pool()

这个通过使用一个技巧利用进程池解决了 GIL 的问题。

当一个线程想要执行 CPU 密集型工作时,会将任务发给进程池。然后进程池会在另外一个进程中启动一个单独的 Python 解释器来工作。当线程等待结果的时候会释放 GIL。

并且,由于计算任务在单 独解释器中执行,那么就不会受限于 GIL 了。在一个多核系统上面,你会发现这个技术可以让你很好的利用多 CPU 的优势。

另外一个解决 GIL 的策略是使用 C 扩展编程技术。

主要思想是将计算密集型任务转移给 C,跟 Python 独立,在工作的时候在 C 代码中释放 GIL。

这可以通过在 C 代码中插入下面这串代码来完成:

#include "Python.h"
...
PyObject *pyfunc(PyObject *self, PyObject *args) {
...
Py_BEGIN_ALLOW_THREADS
...
Py_END_ALLOW_THREADS
...
}

结论

作为一个真实的例子,在多线程的网络编程中神秘 的 stalls 可能是因为其他原因比如一个 DNS 查找延时,而跟 GIL 毫无关系。

最后你需要先去搞懂你的代码是否真的被 GIL 影响到。

同时还要明白 GIL 大部分都应该 只关注 CPU 的处理而不是 I/O.如果你准备使用一个处理器池,注意的是这样做涉及到数据序列化和在不同 Python 解释器通信。

被执行的操作需要放在一个通过 def 语句定义的 Python 函数中, 不能是 lambda、闭包可调用实例等,并且函数参数和返回值必须要兼容 pickle。

C 扩展最重要的特征是它们和 Python 解释器是保持独立的。也就是说,如果你准 备将 Python 中的任务分配到 C 中去执行,你需要确保 C 代码的操作跟 Python 保持独立,这就意味着不要使用 Python 数据结构以及不要调用 Python 的 C API。

也就是说 C 扩展担负起 了大量的计算任务,而不是少数几个计算。

相关文章:

全局解释器锁 GIL

问题 你已经听说过全局解释器锁 GIL,担心它会影响到多线程程序的执行性能。 解决方案 尽管 Python 完全支持多线程编程,但是解释器的 C 语言实现部分在完全并行执行时并不是线程安全的。 实际上,解释器被一个全局解释器锁保护着&#xff…...

github 下载文件加速 https://moeyy.cn/gh-proxy/

GitHub文件链接带不带协议头都可以,支持release、archive以及文件,右键复制出来的链接都是符合标准的。 注意,不支持项目文件夹,请使用Git。 分支源码:https://github.moeyy.xyz/https://github.com/moeyy/project/arc…...

第五章 资源包使用

游戏开发中会大量使用模型文件,图片文件,这些资源都需要事先导入到项目中去。导入的方式非常简单,将这些文件直接复制到项目中的Assets目录下即可。Unity 会在文件添加到 Assets 文件夹时自动检测到这些文件并同步显示在Project视图中。 Uni…...

Linux od命令

Linux od命令用于输出文件内容。 od指令会读取所给予的文件的内容&#xff0c;并将其内容以八进制字码呈现出来。 语法 od [-abcdfhilovx][-A <字码基数>][-j <字符数目>][-N <字符数目>][-s <字符串字符数>][-t <输出格式>][-w <每列字符…...

【15】SCI易中期刊推荐——电子电气 | 仪器仪表(中科院4区)

💖💖>>>加勒比海带<<<💖💖 🍀🍀>>>【YOLO魔法搭配&论文投稿咨询】<<<🍀🍀 ✨✨>>>学习交流 | 温澜潮生 | 合作共赢 | 共同进步<<<✨✨ 📚📚>>>人工智能 | 计算机视觉 | 深度学习Tr…...

基于PaddleServing的串联部署 ocr 识别模型

要点&#xff1a; 使用paddleserving服务 1 首先需要安装PaddleServing部署相关的环境 PaddleServing是PaddlePaddle推出的一种高性能、易扩展、高可用的机器学习服务框架。PaddleOCR中使用PaddleServing主要是为了将训练好的OCR模型部署到线上环境&#xff0c;提供API服务&a…...

java OutputStream学习

1.概要 OutputStream位于java.io&#xff0c;它在Java 实现的IO类库中是一个很基础的抽象类。在层级上&#xff0c;是所有字节输出流类的父类&#xff0c;在功能上&#xff0c;表示接受字节并把它们输出。 2.实现类及子类简介 OutputStream有诸多子类&#xff1a; ByteAr…...

java 上传文件生成二进制流文件

最近在项目中遇到一个问题&#xff1a;需要将上传的文件生成输出流&#xff0c;然后将输出流转换为输入流上传到oss。 -------------------------------------------导出代码实现---------------------------------------------------------- ByteArrayOutputStream baos nu…...

质量小议22 -- 多少分合适

60分万岁~&#xff1f;&#xff1f;&#xff1f;&#xff01;&#xff01;&#xff01; 如果用分数评价质量&#xff0c;多少分合适&#xff1f;60&#xff0c;70&#xff0c;80...还是100&#xff0c;或者 120 对于质量的提升&#xff0c;是雪中送炭&#xff0c;还是锦上添…...

变频器参数设定说明

使用默贝克MT110-0R4-S2B实现下面的练习题&#xff1a; 1、先恢复出厂设置&#xff0c;再输入电机参数&#xff0c;选择静态调谐 2、两种运行模式&#xff1a;多段速&#xff08;8段&#xff09;和简易PLC&#xff08;4段&#xff09; 3、面板启停&#xff0c;运行模式通过外部…...

实用调试技巧

目录&#xff1a; 1.什么是bug&#xff1f; 2.调试是什么&#xff1f;有多重要&#xff1f; 3.debug和release的介绍 4.Windows环境调试介绍 5.一些调试的实例 6.如何写出好(易于调试)的代码 7.编程常见的错误 1.什么是bug&#xff1f; bug--->臭虫、虫子。 为什么含…...

谁是液冷行业真龙头?疯狂的液冷技术!

“人工智能领域AIGC”、“ChatGPT”、“数据特区”、“东数西算”、“数据中心”&#xff0c;可以说是2023年最热的概念&#xff0c;算力提升的背后&#xff0c;处理器的功耗越来越高&#xff0c;想发挥出处理器的最高性能&#xff0c;需要更高的散热效率。 算力井喷之下&…...

自动化运维工具之Ansible

目录 一、自动化运维 1、通过xshell自动化运维 2、Ansible简介 3、Ansible特点及优势 4、Ansible核心程序 5、Ansible工作原理及流程 6、部署Ansible自动化运维工具 7、Ansible常用模块 (1) ansible命令行模块 (2) command模块 (3) shell模块 (4) cron模块 (5) us…...

霍兰德人格分析雷达图

雷达图 Radar Chart 雷达图是多特性直观展示的重要方式 问题分析 霍兰德认为&#xff1a;人格兴趣与职业之间应有一种内在的对应关系 人格分类&#xff1a;研究型、艺术型、社会型、企业型、传统型、现实性 职业&#xff1a;工程师、实验员、艺术家、推销员、记事员、社会工…...

《Odoo开发者模式必知必会》—— 缘起

Odoo作为业界优秀的开源商务软件&#xff0c;在全球范围内拥有广泛的使用者。在领英国际&#xff0c;可以搜索到全球很多国家都有大量odoo人才需求的招聘信息。在国内&#xff0c;虽然已经有为数不少的企业&#xff0c;他们或者已经使用odoo&#xff0c;或者正在了解odoo&#…...

Java8的Options介绍

Java8引入了一个名为 Options 的新类&#xff0c;它是一个容器&#xff0c;可以保存单个值或根本不保存任何值。Optional目的是提供一种更优雅的方式来处理 null 值&#xff0c;这通常会导致NullPointerException。在这篇博客文章中&#xff0c;我们将探索如何在 Java8中使用 O…...

SpringBoot 多数据源及事务解决方案

1. 背景 一个主库和N个应用库的数据源&#xff0c;并且会同时操作主库和应用库的数据&#xff0c;需要解决以下两个问题&#xff1a; 如何动态管理多个数据源以及切换&#xff1f; 如何保证多数据源场景下的数据一致性(事务)&#xff1f; 本文主要探讨这两个问题的解决方案…...

tcpdump使用教程

一、概述 tcpdump是一个功能强大的&#xff0c;用于抓取网络数据包的命令行工具&#xff0c;与带界面的Wireshark一样&#xff0c;基于libpcap库构建。这篇文章主要介绍tcpdump的使用。关于如何使用tcpdump的资料中&#xff0c;最有用的就是tcpdump的两个手册。 tcpdump使用手…...

Zynq-7000、FMQL45T900的GPIO控制(五)---linux应用层配置GPIO输出控制

上文中详细阐述了对应原理图MIO/EMIO的编号&#xff0c;怎么计算获取linux下gpio的编号 本文涉及C代码上传&#xff0c;下载地址 Zynq-7000、FMQL45T900的GPIO控制c语言代码资源-CSDN文库 本文详细记录一下针对获取到gpio的编号&#xff0c;进行配置输出模式&#xff0c;并进…...

带你搞懂人工智能、机器学习和深度学习!

不少高校的小伙伴找我聊入门人工智能该怎么起步&#xff0c;如何快速入门&#xff0c;多长时间能成长为中高级工程师&#xff08;聊下来感觉大多数学生党就是焦虑&#xff0c;毕业即失业&#xff0c;尤其现在就业环境这么差&#xff09;&#xff0c;但聊到最后&#xff0c;很多…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

基于IDIG-GAN的小样本电机轴承故障诊断

目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) ​梯度归一化(Gradient Normalization)​​ (2) ​判别器梯度间隙正则化(Discriminator Gradient Gap Regularization)​​ (3) ​自注意力机制(Self-Attention)​​ 3. 完整损失函数 二…...

JS手写代码篇----使用Promise封装AJAX请求

15、使用Promise封装AJAX请求 promise就有reject和resolve了&#xff0c;就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...