Python threading模块多种锁实现线程同步

简介

线程同步——这是一个很常见的面试题,那么实现线程同步有哪些方式呢?百度一下可以搜出很多相关文章,例如加锁,条件控制,信号量控制等等。那么Python提供了哪些方式呢?我们下面来看看。


目录

简介

目录

正文

基本锁 Lock

关键方法:

样例展示:

源码分析:

递归锁 RLock

关键方法:

样例展示:

源码分析:

条件锁

关键方法:

样例展示:

源码分析:

信号锁

关键方法:

样例展示:

源码分析:

阻塞锁

关键方法:

样例展示:

源码分析:

事件锁

关键方法:

样例展示:

源码分析:

总结


正文

基本锁 Lock

关键方法:

acquire:加锁

release:解锁

样例展示:

 使用方式很简单,先加锁,再解锁,这样可以保证读取文件的顺序是一致的

import threading

lock = threading.Lock()

def readtxt(id):
    lock.acquire()
    with open("test.txt", mode="r", encoding="utf-8") as test:
        for i in test.readlines():
            time.sleep(0.1)
            print("线程"+id,"读模式:",i)
            print(i)
    lock.release()
    
for i in range(2):
    threading.Thread(target=readtxt, args={str(i)}).start()

源码分析:

源码使用的是Python内置的_thread模块实现锁的功能,再往下暂时就看不到了

import _thread
_allocate_lock = _thread.allocate_lock
Lock = _allocate_lock


# python内置_thread线程模块
def allocate_lock() -> LockType: ...

递归锁 RLock

关键方法:

acquire:加锁

release:解锁

样例展示:

和基本锁的用法基本相同,唯一不同的是基本锁在同一线程只能加一个锁,加多了会报错。而递归锁可以同时嵌套多个锁,只要按照加锁锁的数量和顺序,相应解锁。

import threading

rlock = threading.RLock()

def readtxt(id):
    rlock.acquire()
    rlock.acquire()
    with open("test.txt", mode="r", encoding="utf-8") as test:
        for i in test.readlines():
            time.sleep(0.1)
            print("线程"+id,"读模式:",i)
    rlock.release()
    rlock.release()

    
for i in range(2):
    threading.Thread(target=readtxt, args={str(i)}).start()

源码分析:

关键在于如何实现递归添加锁的。

  1. 判断Python内置_thread模块是否存在支持RLock的方法,存在则直接使用,不存在就自己实现(源码中没有发现_thread支持RLock方法
  2. 每次加锁前先判断当前锁ID是否存在,如果存在就计数(count)+1,不存在就创建锁,设置锁的拥有者,计数设置为1
  3. 每次解锁先计数(count)-1,然后判断计数(count)是否清零,0才解锁,锁的拥有者设置为None
import _thread

get_ident = _thread.get_ident

try:
    _CRLock = _thread.RLock
except AttributeError:
    _CRLock = None

_PyRLock = _RLock

def RLock(*args, **kwargs):
    if _CRLock is None:
        return _PyRLock(*args, **kwargs)
    return _CRLock(*args, **kwargs)

class _RLock:
    def __init__(
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值