当前位置: 首页 > 编程笔记 >

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

东门新立
2023-03-14
本文向大家介绍Python线程协作threading.Condition实现过程解析,包括了Python线程协作threading.Condition实现过程解析的使用技巧和注意事项,需要的朋友参考一下

领会下面这个示例吧,其实跟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 gevent协程切换实现详解,包括了Python gevent协程切换实现详解的使用技巧和注意事项,需要的朋友参考一下 一、背景 大家都知道gevent的机制是单线程+协程机制,当遇到可能会阻塞的操作时,就切换到可运行的协程中继续运行,以此来实现提交系统运行效率的目标,但是具体是怎么实现的呢?让我们直接从代码中看一下吧。 二、切换机制 让我们从socket的send、r

  • 本文向大家介绍用Python实现协同过滤的教程,包括了用Python实现协同过滤的教程的使用技巧和注意事项,需要的朋友参考一下 协同过滤 在 用户 —— 物品(user - item)的数据关系下很容易收集到一些偏好信息(preference),比如评分。利用这些分散的偏好信息,基于其背后可能存在的关联性,来为用户推荐物品的方法,便是协同过滤,或称协作型过滤(collaborative filte

  • 本文向大家介绍Java线程协调运行操作实例详解,包括了Java线程协调运行操作实例详解的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Java线程协调运行操作。分享给大家供大家参考,具体如下: 一 点睛 借助于Object类提供的wait()、notify()和notifyAll()三个方法,可实现Java线程协调运行。这三个方法并不属于Thread类,而是属于Object类。但这三个方法

  • 本文向大家介绍python matplotlib折线图样式实现过程,包括了python matplotlib折线图样式实现过程的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了python matplotlib折线图样式实现过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一:简单的折线图 二、多折线折线图 三、折线样式:折线颜色、折

  • 本文向大家介绍python使用协程实现并发操作的方法详解,包括了python使用协程实现并发操作的方法详解的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了python使用协程实现并发操作的方法。分享给大家供大家参考,具体如下: 协程 协程是一种用户态的轻量级线程,又称微线程。 协程拥有自己的寄存器上下文和栈,调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器

  • 本文向大家介绍python实现WebSocket服务端过程解析,包括了python实现WebSocket服务端过程解析的使用技巧和注意事项,需要的朋友参考一下 一种类似Flask开发的WebSocket-Server服务端框架,适用python3.X 1、安装模块Pywss 2、搭建简易服务器 2.1 服务端代码 代码简介 route: 注册请求路径 example_1(request, data