Python学习之线程池与GIL全局锁详解

yizhihongxing

Python学习之线程池与GIL全局锁详解

一、前言

Python是一门非常流行的编程语言,被广泛应用于不同领域。在Python中,线程是一种轻量级的执行单元,可以极大提高程序的并发性能。但是,Python中存在一个全局解释器锁(GIL),限制了多线程并发执行的能力。为了提高并发性能,我们可以使用线程池。

本篇文章旨在详细讲解Python中的线程池与GIL全局锁,帮助大家更好地理解和应用Python的多线程编程。

二、什么是线程池?

线程池是一种常见的并发编程技术,可以在程序启动时预先创建一定数量的线程,并将任务放入队列中。每个线程在空闲时从队列中获取任务并执行,执行完毕后继续等待新任务。使用线程池可以避免重复创建线程的开销,提高程序的性能。

在Python中,我们可以使用标准库中的concurrent.futures模块实现线程池。

示例代码如下:

import concurrent.futures
import time

def long_task(n):
    print(f"开始执行任务{n}")
    time.sleep(2)
    print(f"任务{n}执行完毕")


def main():
    with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
        executor.submit(long_task, 1)

        future_to_task = {executor.submit(long_task, i): i for i in range(2, 7)}

        for future in concurrent.futures.as_completed(future_to_task):
            task = future_to_task[future]
            try:
                result = future.result()
            except Exception as exc:
                print('%r generated an exception: %s' % (task, exc))
            else:
                print(f"任务{task}执行完毕")


if __name__ == "__main__":
    main()

在上述示例中,我们创建了一个ThreadPoolExecutor对象,最大线程数为3。使用executor.submit方法将任务添加到线程池中执行,executor.submit方法会立即返回一个Future对象,表示任务是否执行完成。我们使用字典future_to_task来记录每个Future对象对应的任务编号,以便在任务完成时进行打印。

使用concurrent.futures.as_completed方法可以阻塞地返回已经完成的任务。在任务完成时,我们从future_to_task中获取对应的任务编号,并进行打印。

三、GIL全局解释器锁

GIL全局解释器锁是Python解释器中的一个特性,它保证同一时间只允许一个线程执行Python代码。GIL的存在使得Python的多线程并发能力受到了限制,无法发挥多核CPU的性能优势。

1. GIL的产生原因

GIL的产生是由于Python的内存管理机制和垃圾回收机制。在Python中,有一个叫做PyObject的结构体,它代表了Python中的对象,每个PyObject都保存着对象的引用计数。引用计数表示当前对象被多少个指针引用,当引用计数为0时,对象就会被销毁。

在多线程环境下,如果多个线程同时对同一个PyObject对象进行操作,比如增加引用计数,就会出现竞争情况。为了保证引用计数的正确性,Python解释器实现了一个锁(GIL),保证同一时间只有一个线程能够对PyObject进行操作。

2. GIL的影响

由于GIL的存在,Python的多线程并发能力受到了限制。在多线程环境下,只有一个线程能够执行Python代码,其他线程只能等待GIL的释放。这就意味着Python的多线程程序并不能利用多核CPU的性能优势,只能利用单核CPU的性能。

在CPU密集型任务中,GIL会成为性能瓶颈。但是,在IO密集型任务中,GIL的限制不是很大,因为在IO操作时,线程会释放GIL,其他线程就可以获得执行机会了。因此,如果我们需要并发处理大量IO操作,Python的多线程编程仍然是一种不错的选择。

四、结语

本文主要讲解了Python中的线程池与GIL全局锁。通过本文的阐述,相信大家对Python的多线程编程有了更深入的理解和应用。

另外,需要注意的是,本文只是对Python中线程池和GIL的介绍,实际应用中还需要根据具体场景进行综合考虑和权衡。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python学习之线程池与GIL全局锁详解 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • Python实现自动整理文件的示例代码

    下面是Python实现自动整理文件的示例代码的完整攻略,包含以下步骤: 创建项目目录 首先,我们需要在本地创建一个项目目录,作为我们整理文件的基础。可以选择在桌面或其他文件夹中创建,以下是示例目录结构: automate-files/ ├── organize.py ├── desktop/ │ ├── documents/ │ ├── images/ │ …

    python 2023年5月19日
    00
  • python os模块介绍

    Python os模块介绍 简介 在Python中,os模块是用于与操作系统进行交互的模块,它提供了很多与操作系统相关的功能。 常用功能 获取当前工作目录 使用os模块中的getcwd()函数可以获取当前工作目录。 import os cwd = os.getcwd() print(cwd) 创建目录 使用os模块中的mkdir()函数可以创建目录。 imp…

    python 2023年5月30日
    00
  • python爬虫实现获取下一页代码

    Python爬虫实现获取下一页代码 在本攻略中,我们将介绍如何使用Python爬虫实现获取下一页代码,并提供两个示例。 步骤1:获取网页源代码 在使用Python爬虫获取下一页代码之前,我们需要先获取网页源代码。我们可以使用Python的requests库获取网页源代码。 以下是一个示例,用于获取网页源代码: import requests # 获取网页源代…

    python 2023年5月15日
    00
  • Python字典操作详细介绍及字典内建方法分享

    Python字典操作详细介绍及字典内建方法分享 字典是Python中最常用的数据类型之一,它是一种键/值存储结构,其中每个键都映射到一个值。对于字典,它的实现本质上是一个哈希表(Hash Table),所以在Python中访问字典的元素非常快。 字典的创建 通过以下代码,我们可以创建一个空字典: my_dict = {} 如果想在创建字典时添加一些键值对,可…

    python 2023年5月13日
    00
  • python制作企业邮箱的爆破脚本

    下面是Python制作企业邮箱的爆破脚本的完整攻略: 目标 目标是通过Python编写脚本,实现对企业邮箱系统的爆破测试。 收集信息 在进行爆破之前,需要先收集相关信息。收集的信息包括: 邮箱服务器域名或IP地址 邮箱账户的用户名列表 邮箱账户中的常见密码列表 这些信息可以通过一些常见的信息收集工具和技术来获得,例如搜索引擎、whois查询、网络枚举工具等。…

    python 2023年6月3日
    00
  • Python标准库os.path包、glob包使用实例

    下面是Python标准库os.path包、glob包使用实例的攻略。 什么是os.path包和glob包 os.path包 os.path模块是Python的标准库之一,提供了处理文件和目录路径的函数与变量。在不同的操作系统中,文件和目录的路径分隔符可能是不同的,os.path模块可以自动适配操作系统的路径分隔符。 glob包 glob模块是Python的标…

    python 2023年6月2日
    00
  • Odoo – 在python中减去2个“时间”字段

    【问题标题】:Odoo – Subtract 2 “time” fields in pythonOdoo – 在python中减去2个“时间”字段 【发布时间】:2023-04-07 00:54:01 【问题描述】: for emp in employee: contract_id = contract_pool.search(cr, uid, [(’emp…

    Python开发 2023年4月7日
    00
  • 在Linux命令行终端中使用python的简单方法(推荐)

    在Linux终端中使用Python有很多方法,下面我将介绍一种简单的方法。 步骤1:安装Python 在Linux系统中,Python通常是预安装的。不过,如果你的系统没有预安装Python或者需要安装最新版本的Python,可以从官方网站下载并安装。 步骤2:打开命令行终端 打开Linux命令行终端,可以通过使用Ctrl + Alt + T快捷键来打开。 …

    python 2023年5月18日
    00
合作推广
合作推广
分享本页
返回顶部