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 相关文章推荐
简单介绍Python中的RSS处理
Apr 13 Python
python中string模块各属性以及函数的用法介绍
May 30 Python
Python安装模块的常见问题及解决方法
Feb 05 Python
python基础教程项目五之虚拟茶话会
Apr 02 Python
浅谈Pandas中map, applymap and apply的区别
Apr 10 Python
关于Python的一些学习总结
May 25 Python
Python面向对象之类和对象实例详解
Dec 10 Python
关于Python 的简单栅格图像边界提取方法
Jul 05 Python
Django密码系统实现过程详解
Jul 19 Python
执行Django数据迁移时报 1091错误及解决方法
Oct 14 Python
python中的selenium安装的步骤(浏览器自动化测试框架)
Mar 17 Python
python学习之panda数据分析核心支持库
May 07 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
浅析PHP7的多进程及实例源码
2019/04/14 PHP
PHP pthreads v3使用中的一些坑和注意点分析
2020/02/21 PHP
JavaScript入门教程(1) 什么是JS
2009/01/31 Javascript
js no-repeat写法 背景不重复
2009/03/18 Javascript
javascript 设计模式之单体模式 面向对象学习基础
2010/04/18 Javascript
jquery获取css中的选择器(实例讲解)
2013/12/02 Javascript
javascript实现unicode与ASCII相互转换的方法
2015/12/10 Javascript
你不知道的高性能JAVASCRIPT
2016/01/18 Javascript
浅谈jQuery添加的HTML,JS失效的问题
2016/10/05 Javascript
BootStrap fileinput.js文件上传组件实例代码
2017/02/20 Javascript
Webpack性能优化 DLL 用法详解
2017/08/10 Javascript
浅谈webpack打包之后的文件过大的解决方法
2018/03/07 Javascript
全站最详细的Vuex教程
2018/04/13 Javascript
浅谈VUE防抖与节流的最佳解决方案(函数式组件)
2019/05/22 Javascript
在微信小程序中使用vant的方法
2019/06/07 Javascript
JavaScript eval()函数定义及使用方法详解
2020/07/07 Javascript
解决VUE项目使用Element-ui 下拉组件的验证失效问题
2020/11/07 Javascript
Python实现PS图像调整黑白效果示例
2018/01/25 Python
PyCharm更改字体和界面样式的方法步骤
2019/09/27 Python
python随机生成库faker库api实例详解
2019/11/28 Python
python 实现简单的FTP程序
2019/12/27 Python
Python常驻任务实现接收外界参数代码解析
2020/07/21 Python
python爬虫中url管理器去重操作实例
2020/11/30 Python
canvas 如何绘制线段的实现方法
2018/07/12 HTML / CSS
加拿大在线隐形眼镜专家:PerfectLens.ca
2016/11/19 全球购物
千禧酒店及度假村官方网站:Millennium Hotels and Resorts
2019/05/10 全球购物
为女性购买传统的印度服装和婚纱:Kalkifashion
2019/07/22 全球购物
英国高级健康和美容产品零售商:Life and Looks
2019/08/01 全球购物
2014年开学第一课活动方案
2014/03/06 职场文书
校园安全演讲稿
2014/05/09 职场文书
打架检讨书范文
2015/01/27 职场文书
2015年音乐教师个人工作总结
2015/05/20 职场文书
2016年国培心得体会及反思
2016/01/13 职场文书
手把手教你制定暑期学习计划,让你度过充实的暑假
2019/08/22 职场文书
标准版个人借条怎么写?以及什么是借条?
2019/08/28 职场文书
详解Go语言Slice作为函数参数的使用
2021/07/02 Golang