Condition

class threading.Condition(lock=None

这个类实现条件变量对象。条件变量允许一个或多个线程等待,知道它们被另一个线程唤醒。

如果给出了lock参数而不是None,则它必须是LcokRLock对象,并以它作为底层的锁。否则将默认创建一个RLock对象。

Condition遵循上下文管理协议。

方法:

acquire(*args)

获取锁。这个方法调用底层锁的相应方法。

release()

释放锁。这个方法调用底层锁的相应方法。

wait(timeout=None)

线程挂起,等待被唤醒(其他线程的notify方法)或者发生超时。调用该方法的线程必须先获得锁,否则引发RuntimeError

该方法会释放底层锁,然后阻塞,直到它被另一个线程中的相同条件变量的notify()notify_all()方法唤醒,或者发生超时。一旦被唤醒或超时,它会重新获取锁并返回。

返回值为True,如果给定timeout并发生超时,则返回False

wait_for(predicate, timeout=None)

等待知道条件变量的返回值为Truepredicate应该是一个返回值可以解释为布尔值的可调用对象。可以设置timeout以给定最大等待时间。

该方法可以重复调用wait(),直到predicate的返回值解释为True,或发生超时。该方法的返回值就是predicate的最后一个返回值,如果发生超时,返回值为False

如果忽略超时功能,该方法大致相当于:

  1. while not predicate():
  2. con.wait()

它与wait()的规则相同:调用前必须先获取锁,阻塞时释放锁,并在被唤醒时重新获取锁并返回。

notify(n=1)

默认情况下,唤醒等待此条件变量的一个线程(如果有)。调用该方法的线程必须先获得锁,否则引发RuntimeError

该方法最多唤醒n个等待中的线程,如果没有线程在等待,它就是要给无动作的操作。

注意:要被唤醒的线程实际上不会马上从wait()方法返回(唤醒),而是等到它重新获取锁。这是因为notify()并不会释放锁,需要线程本身来释放(通过wait()或者release())

notify_all()

此方法类似于notify(),但唤醒的时所有等待的线程。

生产者与消费者 -- Condition版

场景:生产者一次性生产5个商品(生产过程中不可购买),之后通知消费者抢购,当商品卖完后,由消费者通知生产者开始生产。

  1. # -*- coding:utf-8 -*-
  2. import threading
  3. import time
  4. num = 0
  5. con = threading.Condition()
  6. class Producer(threading.Thread):
  7. """生产者"""
  8. def run(self):
  9. global num
  10. # 获取锁
  11. con.acquire()
  12. while True:
  13. num += 1
  14. print('生产了1个,现在有{0}个'.format(num))
  15. time.sleep(1)
  16. if num >= 5:
  17. print('已达到5个,不再生产')
  18. # 唤醒消费者
  19. con.notify()
  20. # 等待-释放锁;被唤醒-获取锁
  21. con.wait()
  22. # 释放锁
  23. con.release()
  24. class Customer(threading.Thread):
  25. def __init__(self, *args, **kwargs):
  26. super().__init__(*args, **kwargs)
  27. self.money = 7
  28. def run(self):
  29. global num
  30. while self.money > 0:
  31. # 由于场景是多个消费者进行抢购,如果将获取锁操作放在循环外(如生产者),
  32. # 那么一个消费者线程被唤醒时会锁住整个循环,无法实现另一个消费者的抢购。
  33. # 在循环中添加一套"获取锁-释放锁",一个消费者购买完成后释放锁,其他消费者
  34. # 就可以获取锁来参与购买。
  35. con.acquire()
  36. if num <= 0:
  37. print('没货了,{0}通知生产者'.format(
  38. threading.current_thread().name))
  39. con.notify()
  40. con.wait()
  41. self.money -= 1
  42. num -= 1
  43. print('{0}消费了1个, 剩余{1}个'.format(
  44. threading.current_thread().name, num))
  45. con.release()
  46. time.sleep(1)
  47. print('{0}没钱了-回老家'.format(threading.current_thread().name))
  48. if __name__ == '__main__':
  49. p = Producer(daemon=True)
  50. c1 = Customer(name='Customer-1')
  51. c2 = Customer(name='Customer-2')
  52. p.start()
  53. c1.start()
  54. c2.start()
  55. c1.join()
  56. c2.join()

运行结果:

  1. 生产了1个,现在有1
  2. 生产了1个,现在有2
  3. 生产了1个,现在有3
  4. 生产了1个,现在有4
  5. 生产了1个,现在有5
  6. 已达到5个,不再生产
  7. Customer-1消费了1个, 剩余4
  8. Customer-2消费了1个, 剩余3
  9. Customer-1消费了1个, 剩余2
  10. Customer-2消费了1个, 剩余1
  11. Customer-1消费了1个, 剩余0
  12. 没货了,Customer-2通知生产者
  13. 生产了1个,现在有1
  14. 生产了1个,现在有2
  15. 生产了1个,现在有3
  16. 生产了1个,现在有4
  17. 生产了1个,现在有5
  18. 已达到5个,不再生产
  19. Customer-1消费了1个, 剩余4
  20. Customer-2消费了1个, 剩余3
  21. Customer-1消费了1个, 剩余2
  22. Customer-2消费了1个, 剩余1
  23. Customer-1消费了1个, 剩余0
  24. 没货了,Customer-2通知生产者
  25. 生产了1个,现在有1
  26. 生产了1个,现在有2
  27. 生产了1个,现在有3
  28. 生产了1个,现在有4
  29. 生产了1个,现在有5
  30. 已达到5个,不再生产
  31. Customer-1消费了1个, 剩余4
  32. Customer-2消费了1个, 剩余3
  33. Customer-2消费了1个, 剩余2
  34. Customer-1消费了1个, 剩余1
  35. Customer-1没钱了-回老家
  36. Customer-2消费了1个, 剩余0
  37. 没货了,Customer-2通知生产者
  38. 生产了1个,现在有1
  39. 生产了1个,现在有2
  40. 生产了1个,现在有3
  41. 生产了1个,现在有4
  42. 生产了1个,现在有5
  43. 已达到5个,不再生产
  44. Customer-2消费了1个, 剩余4
  45. Customer-2没钱了-回老家

python多线程--Condition(条件对象)的更多相关文章

  1. Java多线程——Condition条件

    简介 Condition中的await()方法相当于Object的wait()方法,Condition中的signal()方法相当于Object的notify()方法,Condition中的signa ...

  2. python线程condition条件锁应用实例

    import time import threading # 吃火锅鱼丸 guo = [] suo = threading.Condition() #条件锁 # 生产者负责生产 class Produ ...

  3. 关于Python多线程condition变量的应用

    ''' 所谓条件变量,即这种机制是在满足了特定的条件后,线程才可以访问相关的数据. 它使用Condition类来完成,由于它也可以像锁机制那样用,所以它也有acquire方法和release方法,而且 ...

  4. Python 多线程 Condition 的使用

    Condition Condition(条件变量)通常与一个锁关联.需要在多个Contidion中共享一个锁时,可以传递一个Lock/RLock实例给构造方法,否则它将自己生成一个RLock实例. 可 ...

  5. [Python 多线程] Condition (十)

    Condition常用于生产者.消费者模型,为了解决生产者消费者速度匹配问题. 构造方法Condition(lock=None),可以传入一个Lock或RLock对象,默认RLock. 方法: acq ...

  6. Python多线程-Barrier(障碍对象)

    Barrier(parties, action=None, timeout=None) 每个线程通过调用wait()尝试通过障碍,并阻塞,直到阻塞的数量达到parties时,阻塞的线程被同时全部释放. ...

  7. Python多线程-Event(事件对象)

    Event 事件对象管理一个内部标志,通过set()方法将其设置为True,并使用clear()方法将其设置为False.wait()方法阻塞,直到标志为True.该标志初始为False. 方法: i ...

  8. python多线程-Semaphore(信号对象)

    Semaphore(value=1) Semaphore对象内部管理一个计数器,该计数器由每个acquire()调用递减,并由每个release()调用递增.计数器永远不会低于零,当acquire() ...

  9. java并发多线程显式锁Condition条件简介分析与监视器 多线程下篇(四)

    Lock接口提供了方法Condition newCondition();用于获取对应锁的条件,可以在这个条件对象上调用监视器方法 可以理解为,原本借助于synchronized关键字以及锁对象,配备了 ...

随机推荐

  1. C# 结构(struct)的特点

    1.C# 中的结构有以下特点: 结构可带有方法.字段.索引.属性.运算符方法和事件. 结构可定义构造函数,但不能定义析构函数.但是,您不能为结构定义默认的构造函数.默认的构造函数是自动定义的,且不能被 ...

  2. java经典40+分析

      现在是3月份,也是每年开年企业公司招聘的高峰期,同时有许多的朋友也出来找工作.现在的招聘他们有时会给你出一套面试题或者智力测试题,也有的直接让你上机操作,写一段程序.算法的计算不乏出现,基于这个原 ...

  3. Linux安装Oracle 11g Grid Infrastructure 出现OUI-10182错误解决办法

      已确保安装的ORACLE_BASE目录是属于grid:oinstall 但安装时总是报:OUI-10182 The effective user ID does not match the own ...

  4. day3用户交互,格式化输出,数据类型,流程控制

    上节课复习: 1.运行python程序的三步骤:python test.py 1.先启动python解释器 2.将test.py的内容当作普通的字符读入内存 3.python解释器解释执行刚刚读入内存 ...

  5. 【python-crypto】导入crypto包失败的情况,怎么处理

    [python-crypto]导入crypto包失败的情况,怎么处理 是因为你自己安装的python的版本太高,所以自己降版本吧,捣鼓了一下午 pip install crypto pip insta ...

  6. PAT甲级 1128. N Queens Puzzle (20)

    1128. N Queens Puzzle (20) 时间限制 300 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue The & ...

  7. NameNode工作机制

    NameNode工作机制

  8. 查找对端mac地址

    1.ping对端mac: 2.arp命令查找:

  9. java 调用c++程序实例

    1.java程序: package com.zhangshitong; import java.io.File; public class Java2cpp { static{ System.load ...

  10. linux创建、进入、修改目录或者文件权限 ‘ACM’时间是什么?怎么修改?

    cd code 进入code目录,mkdir test 创建test目录,看代码框都输第三行d(目录文件标识符) rwx(user可读可写可执行) rwx(group可读可写可执行) r-x(othe ...