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 break语句详解
Mar 11 Python
Python中无限元素列表的实现方法
Aug 18 Python
Python中isnumeric()方法的使用简介
May 19 Python
Python 正则表达式入门(中级篇)
Dec 07 Python
Python 基础教程之str和repr的详解
Aug 20 Python
使用Python制作自动推送微信消息提醒的备忘录功能
Sep 06 Python
Django框架models使用group by详解
Mar 11 Python
Django自带的用户验证系统实现
Dec 18 Python
利用Python批量识别电子账单数据的方法
Feb 08 Python
用pip给python安装matplotlib库的详细教程
Feb 24 Python
Pytorch中Softmax与LogSigmoid的对比分析
Jun 05 Python
python编程实现清理微信重复缓存文件
Nov 01 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中Session的概念
2006/10/09 PHP
php SQL防注入代码集合
2008/04/25 PHP
浅析PHP程序设计中的MVC编程思想
2014/07/28 PHP
php读取csc文件并输出
2015/05/21 PHP
全面解析PHP验证码的实现原理 附php验证码小案例
2016/08/17 PHP
使用Codeigniter重写insert的方法(推荐)
2017/03/23 PHP
ASP.NET jQuery 实例15 通过控件CustomValidator验证CheckBoxList
2012/02/03 Javascript
jquery验证表单中的单选与多选实例
2013/08/18 Javascript
浅析JQuery中的html(),text(),val()区别
2014/09/01 Javascript
Vue.js每天必学之指令系统与自定义指令
2016/09/07 Javascript
AngularJS 自定义过滤器详解及实例代码
2016/09/14 Javascript
原生js实现对Ajax的封装(仿jquery)
2017/01/22 Javascript
如何获取元素的最终background-color
2017/02/06 Javascript
js实现日历与定时器
2017/02/22 Javascript
详解用函数式编程对JavaScript进行断舍离
2017/09/18 Javascript
Python结合ImageMagick实现多张图片合并为一个pdf文件的方法
2018/04/24 Python
python迭代dict的key和value的方法
2018/07/06 Python
python输出100以内的质数与合数实例代码
2018/07/08 Python
python实现简单名片管理系统
2018/11/30 Python
基于python全局设置id 自动化测试元素定位过程解析
2019/09/04 Python
Django框架HttpRequest对象用法实例分析
2019/11/01 Python
python字典setdefault方法和get方法使用实例
2019/12/25 Python
pytorch 获取tensor维度信息示例
2020/01/03 Python
python全局变量引用与修改过程解析
2020/01/07 Python
Tessabit日本:集世界奢侈品和设计师品牌的意大利精品买手店
2020/01/07 全球购物
施惠特软件测试面试题以及笔试题
2015/05/13 面试题
高级Java程序员面试要点
2013/08/02 面试题
即兴演讲稿
2014/01/04 职场文书
大学生自我评价范文分享
2014/02/21 职场文书
幼儿园毕业园长感言
2014/02/24 职场文书
青春无悔演讲稿
2014/05/08 职场文书
白血病募捐倡议书
2014/05/14 职场文书
MyBatis 动态SQL全面详解
2021/10/05 MySQL
python基础之类属性和实例属性
2021/10/24 Python
Pandas-DataFrame知识点汇总
2022/03/16 Python
WinServer2012搭建DNS服务器的方法步骤
2022/06/10 Servers