threading中的锁

  • threading.Lock

  这个锁是不被某个特定线程所拥有的。一个线程获取了锁,之后任何线程尝试着获取锁,都会失败,包括这个获取了锁的线程自己尝试获取锁。

  例如,如下代码就会堵塞

import threading
lock = threading.Lock()
lock.acquire()
lock.acquire()
lock.release()
lock.release()

  lock.acquire(blocking=True, timeout=-1),返回的为True或者False,分别代表成功和失败。

  默认有两个参数,一个是blocking=True,意思是调用方法的时候没有获取到锁,就会堵塞线程,直到获取到锁为止。

import threading
lock = threading.Lock()
print(lock.acquire(blocking=True))
print(lock.acquire(blocking=False))

# output:
# True
# False

  另一个参数是timeout=-1,表示等待获取锁的时间,-1表示一直等待。如果超过timeout设定的时间还没有获取到锁就会有获取锁失败

import threading
lock = threading.Lock()
print(lock.acquire(blocking=True))
print(lock.acquire(timeout=1))

# output:
# True
# False

  这两个参数设定的时候需要注意,如何设定了timeout为正数,则不能设定blocking=False。因为设定了timeout为正数表明等待设定的时间会阻塞线程,和blocking=False是矛盾的。

  •  threading.RLock

  这个锁可以由同一个线程获取多次,它由除了locked和unlocked状态之外的owning thread和recursion level的概念组成。从一个已经获取了锁的线程中获取锁,需要调用acquire方法,如果该线程已经有锁,那么立刻返回True。如果需要释放锁,则调用release方法。

  注意,acquire()/release()方法成对出现,只有最后一个release()方法才会真正的释放该线程的锁,允许其他线程获取。

  参数和threading.Lock一样。。。

示例:该程序不会一直堵塞

import threading
lock = threading.RLock()
print(lock.acquire())
print(lock.acquire())
lock.release()
lock.release()

# output:
# True
# True
  • threading.Condition

  threading.Condition拥有比Lock和RLock更加细腻度的控制。该对象除了拥有acquire和release方法外还有如下方法:(下面三个方法在没有调用acquire之后和调用release之前是不能调用的)

  • wait交出线程的锁
  • notify通知其他线程条件发生变化,但是并不交出锁
  • notify_all如果有很多线程,那么使用notify_all

我觉得Condition中的线程主要有三种状态

  1. 运行状态:该线程获得控制权,正在运行
  2. 阻塞状态:该线程不可能获得控制权,相当于调用了wait方法,但是没有获得notify通知的线程
  3. 就绪状态:等待获得控制权的线程,该线程获得控制权就可以运行,获得了notify或者notify_all通知的线程

示例:生产者卖火锅丸子,总共生产10个。每生产五个,消费者才能开始吃。消费者吃完了之后,等待生产者生产丸子。

import threading
import time

class Producer(threading.Thread):
    def __init__(self, con):
        self.con = con
        super().__init__()

    def run(self):
        # times = 0
        global num
        self.con.acquire()
        for _ in range(10):
            print("开始添加丸子")
            num += 1
            print("火锅里面丸子的个数为:{}".format(num))
            time.sleep(1)
            if num == 5:
                print("火锅里面的丸子已经到达五个, 无法继续添加了")
                self.con.notify()
                self.con.wait()
            # times += 1
        self.con.release()

class Consumer(threading.Thread):
    def __init__(self, con):
        self.con = con
        super().__init__()

    def run(self):
        self.con.acquire()
        global num
        while num:
            print("开始吃啦!")
            num -= 1
            print("火锅里面的丸子剩余:{}".format(num))
            time.sleep(0.5)
            if num == 0:
                print("火锅里面没有丸子了,快点添加")
                self.con.notify()
                self.con.wait(6)
        self.con.release()
con = threading.Condition()
num = 0
p = Producer(con)
c = Consumer(con)
p.start()
c.start()

猜你喜欢

转载自blog.csdn.net/hsc_1/article/details/81161370