Python全局解释器锁(Global Interpreter Lock,简称 GIL), 互斥锁

简介: Python全局解释器锁(Global Interpreter Lock,简称 GIL), 互斥锁

一.全局解释器锁(Global Interpreter Lock,简称 GIL)

全局解释器锁(Global Interpreter Lock,简称 GIL)是在 CPython 解释器中的一种机制。CPython 是 Python 的官方解释器,它使用 GIL 来确保在任何时刻只有一个线程执行 Python 字节码。

GIL 的存在主要是为了简化 CPython 解释器的实现,使得它能更容易地处理并发情况。然而,GIL 也引入了一些限制,特别是在多核处理器上的并行执行方面。

主要特点和影响:

  1. 单线程执行: 在任何给定的时刻,只有一个线程能够执行 Python 字节码。即使在多核处理器上运行 Python 程序,由于 GIL 的存在,同一时刻只有一个核心在执行 Python 代码。
  2. 对多线程性能的影响: GIL 对于 CPU 密集型任务(计算密集型任务)的性能影响较大,因为它阻止了多个线程的并行执行。然而,在 I/O 密集型任务(例如网络请求、文件读写)中,GIL 的影响较小,因为线程在等待外部资源时可以释放 GIL。
  3. 影响多进程编程: 多进程编程可以在多核系统上实现真正的并行执行,因为每个进程都有自己的 Python 解释器和 GIL。在多进程模型中,每个进程都可以独立运行,不受 GIL 的限制。
  4. Python 中的内存管理: GIL 对于 Python 中的内存管理有一些影响。由于 GIL 的存在,CPython 在处理内存分配和垃圾回收时需要额外的考虑,以确保线程安全。

需要注意的是,GIL 是 CPython 解释器的特性,其他一些 Python 解释器(例如 Jython、IronPython)并不具备 GIL。如果你的应用对并发性能有较高的要求,你可以考虑使用多进程、使用其他解释器,或者使用其他并发编程模型(如异步编程)。

二. 互斥锁

1. 定义

互斥锁(Mutex Lock)是一种同步原语,用于在多线程或多进程环境中控制对共享资源的访问。在 Python 中,你可以使用 threading 模块(用于线程)或 multiprocessing 模块(用于进程)提供的 Lock 类来实现互斥锁。

互斥锁的主要目的是确保在任何时刻只有一个线程(或进程)能够访问共享资源,以防止数据竞态和不一致的状态。在并发编程中,多个线程或进程可能同时访问和修改共享的数据,而互斥锁能够帮助你控制这种访问,确保数据的一致性。

2. 在 Python 中,使用互斥锁通常涉及以下步骤:

  1. 创建互斥锁对象: 使用 threading.Lock()multiprocessing.Lock() 创建一个互斥锁对象。

import threading


# 创建互斥锁

mutex_lock = threading.Lock()



  1. 获取锁(加锁): 在访问共享资源之前,使用 lock.acquire() 获取互斥锁。如果锁已经被其他线程或进程持有,则当前线程(或进程)将被阻塞,直到锁被释放。

mutex_lock.acquire()


  1. 访问共享资源: 在互斥锁的保护下,对共享资源进行读取或修改操作。
  2. 释放锁(解锁): 在访问共享资源完成后,使用 lock.release() 释放互斥锁,以允许其他线程或进程获取锁并访问共享资源。

mutex_lock.release()


3.以下是一个简单的示例,演示了如何使用互斥锁来保护共享资源:

 

import threading
 
# 共享资源
shared_variable = 0
 
# 创建互斥锁
mutex_lock = threading.Lock()
 
def worker():
    global shared_variable
    for _ in range(100000):
        # 获取互斥锁
        mutex_lock.acquire()
        shared_variable += 1
        # 释放互斥锁
        mutex_lock.release()
 
# 创建多个线程
threads = []
for _ in range(5):
    thread = threading.Thread(target=worker)
    threads.append(thread)
    thread.start()
 
# 等待所有线程结束
for thread in threads:
    thread.join()
 
print(f"Final value of shared_variable: {shared_variable}")

       

在这个例子中,多个线程同时对 shared_variable 进行累加操作,通过互斥锁确保了对共享资源的访问是线程安全的。最终输出的 shared_variable 的值应该是 5 * 100000 = 500000

4.互斥锁使用进阶

import multiprocessing
 
def worker(lock, shared_variable):
    for _ in range(5):
        with lock:
            shared_variable.value += 1
            print(f"Process {multiprocessing.current_process().name}: {shared_variable.value}")
            
if __name__ == "__main__":
    # 创建共享变量和互斥锁
    shared_variable = multiprocessing.Value("i", 0)
    lock = multiprocessing.Lock()
 
    # 创建多个进程,每个进程都调用worker函数
    processes = []
    for i in range(3):
        process = multiprocessing.Process(target=worker, args=(lock, shared_variable))
        processes.append(process)
        process.start()
 
    # 等待所有进程结束
    for process in processes:
        process.join()

在上面的例子中,我们使用了multiprocessing.Value创建一个共享的整数变量shared_variable,并使用multiprocessing.Lock创建一个互斥锁lock。在worker函数中,我们使用with lock语句来确保对共享变量的访问是互斥的,以防止多个进程同时修改它。

需要注意的是,这里使用了multiprocessing.Value来创建共享变量,而不是简单的整数。这是因为multiprocessing模块中的数据类型在多个进程之间共享时更安全。在这个例子中,我们使用了整数类型("i"表示整数),但你可以根据需要选择其他类型。

请注意,这里使用的是multiprocessing模块而不是threading模块,因为threading模块在CPython解释器中由于全局解释器锁(GIL)的存在,不能真正实现多核并行。如果你的应用程序需要充分利用多核处理器,使用multiprocessing模块更为合适。

相关文章
|
2月前
|
分布式计算 并行计算 安全
在Python Web开发中,Python的全局解释器锁(Global Interpreter Lock,简称GIL)是一个核心概念,它直接影响了Python程序在多线程环境下的执行效率和性能表现
【6月更文挑战第30天】Python的GIL是CPython中的全局锁,限制了多线程并行执行,尤其是在多核CPU上。GIL确保同一时间仅有一个线程执行Python字节码,导致CPU密集型任务时多线程无法充分利用多核,反而可能因上下文切换降低性能。然而,I/O密集型任务仍能受益于线程交替执行。为利用多核,开发者常选择多进程、异步IO或使用不受GIL限制的Python实现。在Web开发中,理解GIL对于优化并发性能至关重要。
46 0
|
12天前
|
Python
python 协程 自定义互斥锁
【8月更文挑战第6天】这段代码展示了如何在Python的异步编程中自定义一个互斥锁(`CustomMutex`类)。该类通过`asyncio.Lock`实现,并提供`acquire`和`release`方法来控制锁的获取与释放。示例还包含了使用此自定义锁的场景:两个任务(`task1`和`task2`)尝试按序获取锁执行操作,直观地演示了互斥锁的作用。这有助于理解Python协程中互斥锁的自定义实现及其基本用法。
|
2月前
|
开发框架 并行计算 安全
Python的GIL限制了CPython在多核下的并行计算,但通过替代解释器(如Jython, IronPython, PyPy)和多进程、异步IO可规避
【6月更文挑战第26天】Python的GIL限制了CPython在多核下的并行计算,但通过替代解释器(如Jython, IronPython, PyPy)和多进程、异步IO可规避。Numba、Cython等工具编译优化代码,未来社区可能探索更高级的并发解决方案。尽管GIL仍存在,现有策略已能有效提升并发性能。
39 3
|
2月前
|
Python
Python中有效地使用global和globals()来管理全局变量
Python中有效地使用global和globals()来管理全局变量
|
2月前
|
安全 Java Python
GIL是Python解释器的锁,确保单个进程中字节码执行的串行化,以保护内存管理,但限制了多线程并行性。
【6月更文挑战第20天】GIL是Python解释器的锁,确保单个进程中字节码执行的串行化,以保护内存管理,但限制了多线程并行性。线程池通过预创建线程池来管理资源,减少线程创建销毁开销,提高效率。示例展示了如何使用Python实现一个简单的线程池,用于执行多个耗时任务。
30 6
|
1月前
|
安全 API Python
`multiprocessing`是Python的一个标准库,用于支持生成进程,并通过管道和队列、信号量、锁和条件变量等同步原语进行进程间通信(IPC)。
`multiprocessing`是Python的一个标准库,用于支持生成进程,并通过管道和队列、信号量、锁和条件变量等同步原语进行进程间通信(IPC)。
Python语言学习之字母G开头函数使用集锦:global用法之详细攻略
Python语言学习之字母G开头函数使用集锦:global用法之详细攻略
|
7天前
|
算法 程序员 开发工具
百万级Python讲师又一力作!Python编程轻松进阶,豆瓣评分8.1
在学习Python的旅程中你是否正在“绝望的沙漠”里徘徊? 学完基础教程的你,是否还在为选择什么学习资料犹豫不决,不知从何入手,提高自己?
百万级Python讲师又一力作!Python编程轻松进阶,豆瓣评分8.1
|
5天前
|
算法 程序员 开发工具
百万级Python讲师又一力作!Python编程轻松进阶,豆瓣评分8.1
在学习Python的旅程中你是否正在“绝望的沙漠”里徘徊? 学完基础教程的你,是否还在为选择什么学习资料犹豫不决,不知从何入手,提高自己?
|
2天前
|
数据采集 存储 人工智能
掌握Python编程:从基础到进阶的实用指南
【8月更文挑战第17天】 本文旨在通过浅显易懂的语言和实际案例,为初学者和有一定基础的开发者提供一条清晰的Python学习路径。我们将从Python的基本语法入手,逐步深入到面向对象编程、数据科学应用及网络爬虫开发等高级主题。每个部分都配备了代码示例和实操建议,确保读者能够将理论知识转化为实际能力。无论你是编程新手,还是希望提升Python技能的开发者,这篇文章都将为你打开一扇通往高效编程世界的大门。
7 2