Python多线程与GIL锁

news2024/9/21 23:37:03

Python多线程与GIL锁

python多线程

 

Python的多线程编程可以在单个进程内创建多个线程来同时执行多个任务,从而提高程序的效率和性能。Python的多线程实现依赖于操作系统的线程调度器,并且受到全局解释器锁(GIL)的限制,因此在某些情况下,多线程并不能真正实现并行执行。

import threading

def print_numbers():
    for i in range(1, 6):
        print(i)

thread1 = threading.Thread(target=print_numbers)
thread2 = threading.Thread(target=print_numbers)

thread1.start()
thread2.start()

thread1.join()
thread2.join()

print("Done")

上述代码创建了两个线程分别同时去打印1-5数字,但是即使有多个cpu,同一时刻也只能打印一个数字!why?

​ 这是由于Python中的全局解释器锁(GIL)导致的。GIL是一种机制,用于确保在任何给定时间内,只有一个线程在Python解释器中执行字节码。这意味着无论有多少个CPU核心,每个线程都无法并行执行Python字节码。因此在执行CPU密集型任务时,多个线程之间的执行是交替进行的,而不是并行的。因此对于CPU任务,python的多线程是假的。而对于IO任务,确实是真正的多线程。

GIL锁

GIL的存在主要是为了防止Python解释器中的数据结构被多个线程同时修改,导致数据结构出现不一致的情况。通过限制同一时刻只有一个线程能够执行Python字节码,GIL可以确保Python解释器中的数据结构不会被多个线程同时修改,从而保证线程安全。

IO任务

I/O资源(Input/Output resources),是指计算机系统中用于输入输出数据的设备和接口,例如硬盘、网络接口、键盘、鼠标等。在计算机编程中,I/O操作指的是程序和外部设备之间进行的数据传输和交互,如读取文件、网络传输,爬虫等。I/O操作通常是非常耗时的,因为它们需要等待外部设备响应或者等待数据的读取。

这些IO任务通常只占用内存和网络,不占用CPU资源,所以也不占用python解释器,因此如果是IO密集型任务,python的多线程优势才能体现出来,而CPU密集型任务python的多线程效率无法有效提升。

破解GIL锁的限制

如果需要处理CPU密集型任务,可以考虑使用多进程编程,因为在多进程中,每个进程都有自己的解释器和内存空间,从而避免了GIL的限制。可以充分利用多核处理器(必须是真正的多核处理器才能体现,否则还是单进程)的优势。

python多进程

使用Python多进程编程的一般步骤如下:

  1. 导入multiprocessing模块,创建进程池对象。可以通过Pool()函数创建进程池对象,指定最大进程数。
  2. 定义需要执行的任务函数。这个函数应该能够接受任务参数,处理任务,返回任务结果。
  3. 调用进程池对象的map()函数,传入任务函数和任务参数。该函数会将任务参数分配给进程池中的进程执行,并返回任务结果列表。
  4. 处理任务结果。根据任务函数的返回值,对任务结果进行处理。可以使用Python中的其他模块,如pandas、numpy等进行数据处理或结果可视化。

需要注意的是,在Python中使用多进程编程时,进程之间的通信和同步是需要考虑的问题。Python中的multiprocessing模块提供了一些同步原语,如Lock、Semaphore等,用于控制进程之间的访问。此外,也可以使用Python中的Queue模块实现进程之间的通信。

代码示例:

import multiprocessing

def worker(num):
    """任务函数"""
    print('Worker %d is running' % num)
    return num**2

if __name__ == '__main__':
    # 创建进程池对象
    pool = multiprocessing.Pool(processes=4)
    # 任务参数列表
    nums = [1, 2, 3, 4, 5]
    # 执行任务并获取结果
    results = pool.map(worker, nums)
    print(results)

python多进程与多线程的结合

每个进程用多个线程执行,这样可以在每个进程内部实现并行处理IO任务,同时也可以充分利用多核处理器的优势。

代码示例:

import multiprocessing
import threading

def worker(num):
    """线程函数,用于处理任务"""
    print(f"Worker {num} is running...")

def main():
    """主函数,创建多个进程和线程"""
    # 创建3个进程
    processes = []
    for i in range(3):
        p = multiprocessing.Process(target=process_worker, args=(i,))
        processes.append(p)
        p.start()

    # 在每个进程内部创建2个线程
    for p in processes:
        for i in range(2):
            t = threading.Thread(target=worker, args=(i,))
            t.start()

if __name__ == '__main__':
    main()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/819196.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何在 Ubuntu 22.04 下编译 StoneDB for MySQL 8.0 | StoneDB 使用教程 #1

作者:双飞(花名:小鱼) 杭州电子科技大学在读硕士 StoneDB 内核研发实习生 ❝ 大家好,我是 StoneDB 的实习生小鱼,目前正在做 StoneDB 8.0 内核升级相关的一些事情。刚开始接触数据库开发没多久&#xff0c…

第55步 深度学习图像识别:CNN特征层和卷积核可视化(TensorFlow)

基于WIN10的64位系统演示 一、写在前面 (1)CNN可视化 在理解和解释卷积神经网络(CNN)的行为方面,可视化工具起着重要的作用。以下是一些可以用于可视化的内容: (a)激活映射&…

多目标关联(分配)最近邻法

多目标关联(分配)最近邻法 最近邻数据关联 适用于两帧图片的中多目标位置关联,目标轨迹与新目标之间的关联、固定位置下的动目标跟踪关联等问题。 新目标与被跟踪目标的预测位置“最邻近”的观测点作为与航迹相关联的观测。 如有三批目标T…

活字格性能优化技巧-如何在大规模数据量的场景下提升数据访问效率

在上节内容中我们介绍了如何利用数据库主键提升访问性能,本节内容我们继续为大家介绍如何在大规模数据量的场景下提升数据访问效率。 在开始之前先做个小小的实验: 1. 准备一张数据表,内置1000W行记录。 2. 直观感受一下这个表的规模。使用…

数据结构入门指南:单链表(附源码)

目录 前言 尾删 头删 查找 位置前插入 位置后插入 位置删除 位置后删除 链表销毁 总结 前言 前边关于链表的基础如果已经理解透彻,那么接下来就是对链表各功能的实现,同时也希望大家能把这部分内容熟练于心,这部分内容对有关链表部分的…

CustomeG6-canvas

目录 简介 scss 快速上手 语雀 简介 antv/g6是一款基于JavaScript的图形可视化引擎,由阿里巴巴的AntV团队开发。 创建各种类型的图形,如流程图、关系图、树形图等。 G6采用了自己的绘图模型和渲染引擎,使其具备高性能的图形渲染能力。…

npm更新和管理已发布的包

目录 1、更改包的可见性 1.1 将公共包设为私有 ​编辑 使用网站 使用命令行 1.2 将私有包公开 使用网站 使用命令行 2、将协作者添加到用户帐户拥有的私有包 2.1 授予对Web上私有用户包的访问权限 2.2 从命令行界面授予私有包访问权限 2.3 授予对私有组织包的访问权限…

InfiniBand,到底是个啥?

对于InfiniBand,很多搞数通的同学肯定不会陌生。 进入21世纪以来,随着云计算、大数据的不断普及,数据中心获得了高速发展。而InfiniBand,就是数据中心里的一项关键技术,地位极为重要。 尤其是今年以来,以Ch…

春秋云镜 CVE-2021-32682

春秋云镜 CVE-2021-32682 elFinder RCE 靶标介绍 elFinder是一套基于Drupal平台的、开源的AJAX文件管理器。该产品提供多文件上传、图像缩放等功能;elFinder 存在安全漏洞,攻击者可利用该漏洞在托管elFinder PHP连接器的服务器上执行任意代码和命令。 启动场景 漏…

金蝶管易云 X Hologres:新一代全渠道电商ERP最佳实践

业务简介 金蝶管易云是金蝶集团旗下专注提供电商企业管理软件服务的子公司,成立于2008年,是国内最早的电商ERP服务商之一,目前已与300主流电商平台建有合作关系,以企业数据为驱动,深度融合线上线下数据,为…

pytorch学习——正则化技术——丢弃法(dropout)

一、概念介绍 在多层感知机(MLP)中,丢弃法(Dropout)是一种常用的正则化技术,旨在防止过拟合。(效果一般比前面的权重衰退好) 在丢弃法中,随机选择一部分神经元并将其输出…

HCIP中期实验

1、该拓扑为公司网络,其中包括公司总部、公司分部以及公司骨干网,不包含运营商公网部分。 2、设备名称均使用拓扑上名称改名,并且区分大小写。 3、整张拓扑均使用私网地址进行配置。 4、整张网络中,运行OSPF协议或者BGP协议的设备…

Hadoop 之 Hive 4.0.0-alpha-2 搭建(八)

Hadoop 之 Hive 搭建与使用 一.Hive 简介二.Hive 搭建1.下载2.安装1.解压并配置 HIVE2.修改 hive-site.xml3.修改 hadoop 的 core-site.xml4.启动 三.Hive 测试 一.Hive 简介 Hive 是基于 Hadoop 的数据仓库工具,可以提供类 SQL 查询能力 二.Hive 搭建 1.下载 H…

linux 安装FTP

检查是否已经安装 $] rpm -qa |grep vsftpd vsftpd-3.0.2-29.el7_9.x86_64出现 vsftpd 信息表示已经安装,无需再次安装 yum安装 $] yum -y install vsftpd此命令需要root执行或有sudo权限的账号执行 /etc/vsftpd 目录 ftpusers # 禁用账号列表 user_list # 账号列…

【Ajax】笔记-设置CORS响应头实现跨域

CORS CORS CORS是什么? CORS(Cross-Origin Resource Sharing),跨域资源共享。CORS是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持get和post请求。跨域资源共享标准新增了一组HTTP首…

VSCode格式化shell脚本

安装格式化插件:shell-format 用VSCode打开shell脚本之后,按格式化快捷键CtrlAltF,会提示没有格式化shell的工具,然后安装插件,我装的是这个插件:shell-format。 介绍:https://marketplace.vis…

2.C语言数据类型

常量与变量 1.**常量:**程序运行中,值不改变的量 变量:int num5;值可以变的量 2 C语言三种简单数据类型:整型,实型,字符型 %c %d %ld %s %f整型-进制的转换 **1.十进制:**默认的进…

SpringBoot使用JKS或PKCS12证书实现https

SpringBoot使用JKS或PKCS12证书实现https 生成JKS类型的证书 可以利用jdk自带的keytool工具来生成证书文件, 默认生成的是JKS证书 cmd命令如下: 执行如下命令,并按提示填写证书内容,最后会生成server.keystore文件 keytool -genkey tomcat…

ChatGPT在商业世界中的创新应用:颠覆传统营销与客户关系管理

🌷🍁 博主 libin9iOak带您 Go to New World.✨🍁 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~&#x1f33…