python中threading.Semaphore和threading.Lock的具体使用

 更新时间:2023年08月10日 11:29:09   作者:liulanba  
python中的多线程是一个非常重要的知识点,本文主要介绍了python中threading.Semaphore和threading.Lock的具体使用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

threading.Semaphore

定义:threading.Semaphore 是 Python 中的线程同步原语,用于控制并发线程的访问数量。Semaphore 类可以创建一个计数器,该计数器限制了同时获取资源的线程数量。其中的两个主要方法是 acquire() 和 release()。

方法:acquire(): 当调用 acquire() 方法时,线程会尝试获取资源的访问权限。如果当前计数器的值大于零,线程可以成功获取资源并将计数器减一;如果当前计数器的值为零,线程将被阻塞,直到有其他线程释放资源。
release(): 当线程使用完资源后,应该调用 release() 方法释放资源的访问权限,这将使计数器的值加一,允许其他线程获取资源。

示例

演示了 Semaphore 的使用:

import threading
semaphore = threading.Semaphore(2)  # 创建一个允许两个线程同时访问的 Semaphore
def worker():
    print('Worker is acquiring semaphore')
    semaphore.acquire()  # 获取资源的访问权限
    print('Worker has acquired semaphore')
    # 执行需要访问资源的操作
    print('Worker is releasing semaphore')
    semaphore.release()  # 释放资源的访问权限
    print('Worker has released semaphore')
# 创建多个线程
for i in range(5):
    t = threading.Thread(target=worker)
    t.start()

Semaphore 的初始计数器值为 2,因此最多允许两个线程同时获取资源的访问权限。其他线程会在调用 acquire() 方法时被阻塞,直到有线程调用 release() 方法释放资源。

使用 Semaphore 可以有效地控制并发线程的访问,例如限制同时访问某个共享资源的线程数量,或者控制并发请求的频率等。

threading.Lock

Python 中的线程锁,用于在多线程环境下保护共享资源,防止多个线程同时访问造成数据不一致或竞争条件的问题。下面是关于 threading.Lock 的详细解释和使用方法:

创建锁对象

import threading
lock = threading.Lock()

获取锁

在进入临界区之前,需要先获取锁。如果锁已经被其他线程获取,则当前线程会阻塞,直到获取到锁为止。
使用 acquire() 方法获取锁:

lock.acquire()

或者使用 with 语句来自动获取和释放锁:

with lock:
    # 执行临界区代码

释放锁

在完成临界区代码的执行后,需要释放锁,让其他线程可以获取锁并执行临界区代码。
使用 release() 方法释放锁:

lock.release()

或者通过 with 语句自动释放锁。
锁的嵌套

同一个线程可以多次获取同一个锁,但需要相应地释放相同次数的锁才能完全释放。
如果没有正确地释放锁的次数与获取锁的次数匹配,可能会导致死锁或其他线程同步问题。

import threading
lock = threading.Lock()
def thread_func():
    with lock:
        # 执行临界区代码
        print("Thread acquired lock")
# 创建多个线程
threads = []
for _ in range(5):
    t = threading.Thread(target=thread_func)
    threads.append(t)
    t.start()
# 等待所有线程执行完毕
for t in threads:
    t.join()

在使用 threading.Lock 时,需要注意以下几点:

1.锁的作用范围应该尽量缩小,只在必要的代码块内使用,避免不必要的线程阻塞。
2.在使用锁的同时,需要注意避免死锁(多个线程相互等待对方释放锁的情况)和竞争条件(多个线程同时修改共享资源的情况)。
3.尽量使用 with 语句来自动获取和释放锁,以避免忘记释放锁的情况发生。
4.锁的性能开销较大,过多地使用锁可能会影响程序的性能。因此,在设计多线程程序时,应该合理使用锁来平衡线程安全和性能的需求。

区别

threading.Lock 和 threading.Semaphore 都是用于线程同步的工具,但在某些方面有一些区别。

功能差异

threading.Lock 是最基本的线程锁,只有两种状态:锁定(locked)和非锁定(unlocked)。一次只允许一个线程获取锁并执行临界区代码。
threading.Semaphore 是一个计数信号量,可以设置初始计数值,并且可以允许多个线程同时获取资源。当计数值大于 1 时,允许多个线程同时执行临界区代码。
计数

threading.Lock 只有两种状态,因此只能用于控制同一时刻只有一个线程访问临界区。
threading.Semaphore 可以通过设置计数值来控制同时访问临界区的线程数量。计数值可以大于 1,允许多个线程同时访问。
释放锁的方式

threading.Lock 必须由获取锁的线程来释放锁,即只有获得锁的线程才能解锁。
threading.Semaphore 可以由任意线程来释放信号量,即可以由其他线程来解锁。
选择使用哪种工具取决于具体的需求。如果只需要控制同一时刻只有一个线程访问临界区,可以使用 threading.Lock。如果需要控制同时访问临界区的线程数量,可以使用 threading.Semaphore。

到此这篇关于python中threading.Semaphore和threading.Lock的具体使用的文章就介绍到这了,更多相关python threading.Semaphore threading.Lock内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python使用protobuf序列化和反序列化的实现

    Python使用protobuf序列化和反序列化的实现

    protobuf是一种二进制的序列化格式,相对于json来说体积更小,传输更快,本文主要介绍了Python使用protobuf序列化和反序列化的实现,感兴趣的可以了解一下
    2021-05-05
  • python QT界面关闭线程池的线程跟随退出完美解决方案

    python QT界面关闭线程池的线程跟随退出完美解决方案

    这篇文章主要介绍了python QT界面关闭,线程池的线程跟随退出解决思路方法,本文给大家分享两种方法结合实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-11-11
  • 基于python的itchat库实现微信聊天机器人(推荐)

    基于python的itchat库实现微信聊天机器人(推荐)

    这篇文章主要介绍了基于python的itchat库实现微信聊天机器人,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-10-10
  • Python使用Gradio实现免费的内网穿透

    Python使用Gradio实现免费的内网穿透

    内网穿透是一种将内部网络服务暴露到公共网络的技术,可以让外部用户访问内部网络上的服务,本文将介绍如何使用Gradio实现免费的内网穿透,需要的可以参考下
    2024-03-03
  • pygame实现中文输入框的示例

    pygame实现中文输入框的示例

    本文主要介绍了pygame实现中文输入框的示例,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • Python报错:PermissionError: [Errno 13] Permission denied的解决办法

    Python报错:PermissionError: [Errno 13] Permission denied的解

    这篇文章主要给大家介绍了关于Python报错:PermissionError: [Errno 13] Permission denied的解决办法,文中给出了详细的解决办法,需要的朋友可以参考下
    2022-02-02
  • 浅谈Python协程asyncio

    浅谈Python协程asyncio

    今天给大家带来的是关于Python的相关知识,文章围绕着Python协程展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下
    2021-06-06
  • python itsdangerous模块的具体使用方法

    python itsdangerous模块的具体使用方法

    这篇文章主要介绍了python itsdangerous模块的具体使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • 用python生成mysql数据库结构文档

    用python生成mysql数据库结构文档

    大家好,本篇文章主要讲的是用python生成mysql数据库结构文档,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-01-01
  • python字符串str和字节数组相互转化方法

    python字符串str和字节数组相互转化方法

    下面小编就为大家带来一篇python字符串str和字节数组相互转化方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03

最新评论