Python线程协作threading.Condition实现过程解析


Posted in Python onMarch 12, 2020

领会下面这个示例吧,其实跟java中wait/nofity是一样一样的道理

import threading


# 条件变量,用于复杂的线程间同步锁
"""
需求:
  男:小姐姐,你好呀!
  女:哼,想泡老娘不成?
  男:对呀,想泡你
  女:滚蛋,门都没有!
  男:切,长这么丑, 还这么吊...
  女:关你鸟事!

"""
class Boy(threading.Thread):
  def __init__(self, name, condition):
    super().__init__(name=name)
    self.condition = condition

  def run(self):
    with self.condition:
      print("{}:小姐姐,你好呀!".format(self.name))
      self.condition.wait()
      self.condition.notify()

      print("{}:对呀,想泡你".format(self.name))
      self.condition.wait()
      self.condition.notify()

      print("{}:切,长这么丑, 还这么吊...".format(self.name))
      self.condition.wait()
      self.condition.notify()


class Girl(threading.Thread):
  def __init__(self, name, condition):
    super().__init__(name=name)
    self.condition = condition

  def run(self):
    with self.condition:
      print("{}:哼,想泡老娘不成?".format(self.name))
      self.condition.notify()
      self.condition.wait()

      print("{}:滚蛋,门都没有!".format(self.name))
      self.condition.notify()
      self.condition.wait()

      print("{}:关你鸟事!".format(self.name))
      self.condition.notify()
      self.condition.wait()


if __name__ == '__main__':
  condition = threading.Condition()
  boy_thread = Boy('男', condition)
  girl_thread = Girl('女', condition)

  boy_thread.start()
  girl_thread.start()

Condition的底层实现了__enter__和 __exit__协议.所以可以使用with上下文管理器

由Condition的__init__方法可知,它的底层也是维护了一个RLock锁

def __enter__(self):
    return self._lock.__enter__()
def __exit__(self, *args):
    return self._lock.__exit__(*args)
def __exit__(self, t, v, tb):
    self.release()
def release(self):
    """Release a lock, decrementing the recursion level.

    If after the decrement it is zero, reset the lock to unlocked (not owned
    by any thread), and if any other threads are blocked waiting for the
    lock to become unlocked, allow exactly one of them to proceed. If after
    the decrement the recursion level is still nonzero, the lock remains
    locked and owned by the calling thread.

    Only call this method when the calling thread owns the lock. A
    RuntimeError is raised if this method is called when the lock is
    unlocked.

    There is no return value.

    """
    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()

至于wait/notify是如何操作的,还是有点懵.....

wait()方法源码中这样三行代码

waiter = _allocate_lock() #从底层获取了一把锁,并非Lock锁
waiter.acquire()
self._waiters.append(waiter) # 然后将这个锁加入到_waiters(deque)中
saved_state = self._release_save() # 这是释放__enter__时的那把锁???

notify()方法源码

all_waiters = self._waiters  
waiters_to_notify = _deque(_islice(all_waiters, n))# 从_waiters中取出n个
if not waiters_to_notify:  # 如果是None,结束
   return
for waiter in waiters_to_notify: # 循环release
   waiter.release()
   try:
     all_waiters.remove(waiter) #从_waiters中移除
   except ValueError:
     pass

大体意思: wait先从底层创建锁,acquire, 放到一个deque中,然后释放掉with锁, notify时,从deque取拿出锁,release

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
使用beaker让Facebook的Bottle框架支持session功能
Apr 23 Python
基于Python实现的微信好友数据分析
Feb 26 Python
Tensorflow实现卷积神经网络用于人脸关键点识别
Mar 05 Python
使用anaconda的pip安装第三方python包的操作步骤
Jun 11 Python
python实现图片识别汽车功能
Nov 30 Python
使用python进行波形及频谱绘制的方法
Jun 17 Python
Django实现发送邮件功能
Jul 18 Python
python判断链表是否有环的实例代码
Jan 31 Python
python Shapely使用指南详解
Feb 18 Python
jupyter notebook插入本地图片的实现
Apr 13 Python
python3.6中anaconda安装sklearn踩坑实录
Jul 28 Python
Python连续赋值需要注意的一些问题
Jun 03 Python
Python 实现网课实时监控自动签到、打卡功能
Mar 12 #Python
Python基于read(size)方法读取超大文件
Mar 12 #Python
Python函数生成器原理及使用详解
Mar 12 #Python
python deque模块简单使用代码实例
Mar 12 #Python
python中安装django模块的方法
Mar 12 #Python
python3 sorted 如何实现自定义排序标准
Mar 12 #Python
Python dict和defaultdict使用实例解析
Mar 12 #Python
You might like
php MySQL与分页效率
2008/06/04 PHP
php中分页及SqlHelper类用法实例
2017/01/12 PHP
PHP数组与字符串互相转换实例
2020/05/05 PHP
JQuery获取样式中的background-color颜色值的问题
2013/08/20 Javascript
可自己添加html的伪弹出框实现代码
2013/09/08 Javascript
Node.js文件操作详解
2014/08/16 Javascript
基于jQuery滑动杆实现购买日期选择效果
2015/09/15 Javascript
jQuery遮罩层效果实例分析
2016/01/14 Javascript
JavaScript中的ajax功能的概念和示例详解
2016/10/17 Javascript
JS条形码(一维码)插件JsBarcode用法详解【编码类型、参数、属性】
2017/04/19 Javascript
ExtJs的Ext.Ajax.request实现waitMsg等待提示效果
2017/06/14 Javascript
jq源码解析之绑在$,jQuery上面的方法(实例讲解)
2017/10/13 jQuery
Angular4.0中引入laydate.js日期插件的方法教程
2017/12/25 Javascript
解决element UI 自定义传参的问题
2018/08/22 Javascript
vue实现类似淘宝商品评价页面星级评价及上传多张图片功能
2018/10/29 Javascript
layui 富文本编辑器和textarea值的相互传递方法
2019/09/18 Javascript
Vue3 源码导读(推荐)
2019/10/14 Javascript
vue动态禁用控件绑定disable的例子
2019/10/28 Javascript
关于vue表单提交防双/多击的例子
2019/10/31 Javascript
uni-app实现获取验证码倒计时功能
2020/11/01 Javascript
[01:03]DOTA2新的征程 你的脚印值得踏上
2014/08/13 DOTA
[01:08]DOTA2次级职业联赛 - Wings 战队宣传片
2014/12/01 DOTA
[41:52]2018DOTA2亚洲邀请赛3月29日 小组赛A组 TNC VS OpTic
2018/03/30 DOTA
详解在Python程序中使用Cookie的教程
2015/04/30 Python
浅谈pandas用groupby后对层级索引levels的处理方法
2018/11/06 Python
Flask框架学习笔记之模板操作实例详解
2019/08/15 Python
Python字符串三种格式化输出
2020/09/17 Python
荟萃全球保健品:维他购
2018/05/09 全球购物
美国领先的眼镜和太阳镜在线零售商:Glasses.com
2019/08/26 全球购物
优秀应届毕业生自荐书
2014/06/29 职场文书
思想作风整顿个人剖析材料
2014/10/06 职场文书
教师创先争优承诺书
2015/04/27 职场文书
2015暑期社会实践调查报告
2015/07/14 职场文书
2016年“世界气象日”广播稿
2015/12/17 职场文书
python中如何对多变量连续赋值
2021/06/03 Python
纯 CSS 自定义多行省略的问题(从原理到实现)
2021/11/11 HTML / CSS