【第22期】观点:IT 行业加班,到底有没有价值?

python2.7 threading 模块 二 Lock RLock

原创 2016年08月30日 23:13:31

1.Lock

Lock的概念很简单,就不多解释了

锁有两种状态:被锁(locked)和没有被锁(unlocked)。拥有acquire()和release()两种方法,并且遵循一下的规则:

  • 如果一个锁的状态是unlocked,调用acquire()方法改变它的状态为locked
  • 如果一个锁的状态是locked,acquire()方法将会阻塞,直到另一个线程调用release()方法释放了锁;
  • 如果一个锁的状态是unlocked调用release()会抛出RuntimeError异常;
  • 如果一个锁的状态是locked,调用release()方法改变它的状态为unlocked。

API 所有的操作都是atomically.

  • Lock.acquire([blocking])
  • Lock.release()

    参数 blocking:

  • True(the default):一直阻塞直到锁被realse.

  • False:如果锁被占用,不阻塞立马返回false

ps:这是python2.7的Lock.acquire(), python3.x的Lock.acquire(blocking=True, timeout=-1)多了一个超时设置。

一个简单的小例子:

import threading
import time

class MyThread(threading.Thread):
    def run(self):
        global num 
        time.sleep(1)

        if mutex.acquire():  
            num = num+1
            msg = self.name+' set num to '+str(num)
            print msg
            mutex.release()
num = 0
mutex = threading.Lock()
def test():
    for i in range(5):
        t = MyThread()
        t.start()
if __name__ == '__main__':
    test()

运行结果:

Thread-3 set num to 1
Thread-4 set num to 2
Thread-5 set num to 3
Thread-2 set num to 4
Thread-1 set num to 5

2.RLock

可重入锁,也叫做递归锁,指的是同一线程 外层函数获得锁之后 ,内层递归函数仍然有获取该锁的代码,但不受影响。

有Lock了为什么还需要RLock呢?可重入锁最大的作用是在需要重复获得锁的情况下(如:递归调用)避免死锁!!!

RLock对象是Lock对象的一个变种,但是它是一种可重入的Lock,其内部维护着一个Lock对象,还有一个计数器。

下面是RLock的acquire()实现。如果调用acquire()的线程是资源的所有者,记录调用acquire()次数的计数器就会加1。如果不是,就将试图去获取锁。线程第一次获得锁时,锁的拥有者将会被保存,同时计数器初始化为1

def acquire(self, blocking=1):
    me = _get_ident()
    if self.__owner == me:
        self.__count = self.__count + 1
        ...
        return 1
    rc = self.__block.acquire(blocking)
    if rc:
        self.__owner = me
        self.__count = 1
        ...
    ...
    return rc

可重入锁(RLock)的release()方法。首先它会去确认调用者是否是锁的拥有者。如果是的话,计数器减1;如果计数器为0,那么锁将会被释放,这时其他线程就可以去获取锁了。

def release(self):
    if self.__owner != _get_ident():
        raise RuntimeError("cannot release un-acquired lock")
    self.__count = count = self.__count - 1
    if not count:
        self.__owner = None
        self.__block.release()
        ...
    ...

使用示例:

1.线程安全的访问一个class,且在一个class 中的某个方法类访问了该类的其他方法。

class X:
    def __init__(self):
        self.a = 1
        self.b = 2
        self.lock = threading.RLock()

    def changeA(self):
        with self.lock:
            self.a = self.a + 1

    def changeB(self):
        with self.lock:
            self.b = self.b + self.a

    def changeAandB(self):
        # you can use chanceA and changeB threadsave!
        with self.lock:
            self.changeA() # a usual lock would block in here
            self.changeB()

2.递归调用

lock = threading.RLock()
def a(...):
     with lock:

         a(...) # somewhere inside

还有两个比较常见的重要的Objects: Condition ,Semaphore 下篇博客再写吧~~~

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

python多线程中互斥锁Threading.Lock的简单应用

每个线程互相独立,相互之间没有任何关系,但是在同一个进程中的资源,线程是共享的,如果不进行资源的合理分配,对数据造成破坏,使得线程运行的结果不可预期。这种现象称为“线程不安全”。

python with 语句研究

原文地址:   http://blog.csdn.net/huithe/article/details/6658831 import sys class test: def __en...

Python中Lock与RLock

在threading模块中,定义两种类型的琐:threading.Lock和threading.RLock。它们之间有一点细微的区别,通过比较下面两段代码来说明: import threading ...

org.eclipse.jgit.errors.LockFailedException: Cannot lock D:\xxx\.git\index

用Eclipse+EGit项目开发,Commit 时提示:完整错误日志:eclipse.buildId=4.6.0.I20160606-1100 java.version=1.8.0_31 java....

安装freeswitch碰到的问题

1.按照链接“ubuntu12.04安装freeSWITCH及fusionPBX”的步骤,安装过程比较奥顺利,但是输入“freeswitch -c”启动FS时,提示:Cannot open pid f...

安装freeswitch碰到的问题

问题1.Cannot open pid file /usr/local/freeswitch/run/freeswitch.pid 问题2.Cannot lock pid file /usr/loc...

ORA-01157: cannot identify/lock data file n 故障一例

最近在使用swingbench的时候碰到了ORA-01157故障,下面是其具体描述与解决。1、故障现象 --查询视图dba_data_files时出现ORA-01157故障 SQL> select...

rm: cannot remove `/var/lib/dpkg/lock': Read-only file system 修复磁盘并成功启动

为了解药所一个rar文件,我按照unrar: 但是因为寝室网络不给力,所以造成以下的奇怪报错: root@ubuntu:/home/zhangbin/sk_m# apt-get insta...

【精】ORA-01157: cannot identify/lock data file 6 - see DBWR trace file ORA-01110: 解决方法

删除了数据文件,启动数据库报错 ORA-01157: cannot identify/lock data file 6 - see DBWR trace file ORA-01110: 解决方法 两个...

ThreadLock--如何破除线程同步现象

线程同步现象是当第一个线程在执行时,并没有执行完时,另一个线程将其打断,并执行自己的线程、、、、、好了大半天,理解到半吊子的程度。。。希望这玩意以后是个鸡肋。。。  package heng.java...
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)