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的简单应用

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

python 线程的同步和互斥

先从一个简单的demo开始说起:
  • xluren
  • xluren
  • 2014年11月10日 13:33
  • 7395

python 并发编程(多进程、多线程、gevent)

本人原创,转载请注明出处,合法转载 1.python 多进程+gevent实现并发 #!/bin/env python #-*- coding: UTF-8 -*- from __future__ ...
  • yanshu2012
  • yanshu2012
  • 2015年12月30日 15:42
  • 2338

关于Python的进程线程协程之threading模块(二)Lock,RLock对象以及Semaphore,BoundedSemaphore对象

关于Python的进程线程协程之threading模块(二)Lock对象与RLock对象 Semaphore对象,BoundedSemaphore对象 线程锁:由于线程之间是随机调度的,并且每个线...
  • ChangerJJLee
  • ChangerJJLee
  • 2017年04月28日 17:24
  • 957

Python多线程编程(threading ):使用Lock互斥锁RLock

互斥锁概念 Python编程中,引入了对象互斥锁的概念,来保证共享数据操作的完整性。每个对象都对应于一个可称为” 互斥锁” 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。在Pyt...
  • u013636377
  • u013636377
  • 2016年03月04日 14:25
  • 364

python中threading的高级函数应用解析 Lock Rlock Condition Semaphore Timer Event Semaphore对象

继上一篇threading高级应用讲述了thread对象的使用,此篇将要讲述Lock Rlock Condition Semaphore Timer Event Semaphore对象的使用方法。Lo...
  • Winterto1990
  • Winterto1990
  • 2015年08月23日 22:27
  • 1513

python2.7 threading 模块 三 Condition Semaphore

1.ConditionCondition被称为条件变量,除了提供与Lock类似的acquire和release方法外,还提供了wait和notify方法。线程首先acquire一个条件变量,然后判断一...
  • karchar
  • karchar
  • 2016年09月01日 20:22
  • 328

python2.7 threading 模块 一 Thread Timer Event

线程,多线程编程基本概念就不多讲了。这个就对常用的Object 作一个总结吧 1.Thread Thread 可以理解为单独执行的某一项操作(activity),创建一个Thread有两种方式和J...
  • karchar
  • karchar
  • 2016年08月26日 17:03
  • 376

Python:使用threading模块实现多线程编程四[使用Lock互斥锁]

前面已经演示了Python:使用threading模块实现多线程编程二两种方式起线程和Python:使用threading模块实现多线程编程三threading.Thread类的重要函数,这两篇文章的...
  • zhou191954
  • zhou191954
  • 2012年12月03日 22:34
  • 355

python多线程中Lock()与RLock()锁

资源总是有限的,程序运行如果对同一个对象进行操作,则有可能造成资源的争用,甚至导致死锁 也可能导致读写混乱锁提供如下方法: 1.Lock.acquire([blocking]) 2.Lock....
  • comprel
  • comprel
  • 2017年05月29日 01:38
  • 4341
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:python2.7 threading 模块 二 Lock RLock
举报原因:
原因补充:

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