python标准库threading源码解读【二】

转载至我的知乎文章:https://zhuanlan.zhihu.com/p/93024096
紧接上一篇文章:https://www.jianshu.com/p/5a488fab56cb

分割线

目录

1.Event的介绍和用法

2.Event源码解析

分割线
1.Event的介绍和用法

可以参考下:
https://cloud.tencent.com/developer/article/1328495
Event中的锁通过Condition实现,用到了类Condition中的wait()和notify_all()方法。
Event提供了一个信号标志flag,利用flag的状态就可以实现线程之间的相互依赖;包含wait(),clear(),set(),is_set()方法和私有方法_reset_internal_locks()。

is_set() 获取event的设置值,默认为False
set() 设置event的值为True
clear() 设置event的值为False
wait() 等到event的值被设为True就执行

# 代码来自上述链接
import threading
import time

def traffic_light(event):
    count = 0
    event.set()
    while True:
        # 如果计数器[0, 5)之间, 红灯,event=False
        if 0 <= count < 5:
            event.clear()
            print("light is Red")
        # 如果计数器[5, 10)之间, 绿灯,event=True
        elif 5 <= count < 10:
            event.set()
            print("light is Green")
        # 如果计数器大于10,红灯,将event设置为False,计数器置为0
        else:
            event.clear()
            count = 0
        time.sleep(1)
        count += 1

def car(name, event):
    while True:
        if not event.is_set():
            # event为False, 表示红灯, 车只能等待
            print("RED, the %s is waiting..." % name)
            # 此处会阻塞住,直到event被设置为True在执行
            event.wait()
            print("Green, The %s going...." % name)

e = threading.Event()
light = threading.Thread(target=traffic_light, args=(e,))
light.start()
car1 = threading.Thread(target=car, args=("Tesla", e, ))
car1.start()

线程car在输出“RED。。。。。。”之后会在wait()中一直等待,直到event的信号标志量为True;
线程light在0-5时,只会调用event.clear(),event的信号标志量一直为False;线程car没有动静;
线程light在6-10时,只会调用event.set(),event的信号标志量一直为True;线程car可以被调用;
实现了线程car对线程light的依赖。

2.Event源码解析

直接看源码

源码 1/3
class Event:
    def __init__(self):
        self._cond = Condition(Lock())
        self._flag = False

    def _reset_internal_locks(self):
        # private!  called by Thread._reset_internal_locks by _after_fork()
        self._cond.__init__(Lock())

    def is_set(self):
        """Return true if and only if the internal flag is true."""
        return self._flag

    isSet = is_set

def init(self):
定义condition锁和标志量flag
def _reset_internal_locks(self):
好像是线程异常退出的时候,重新设置线程锁condition的东西,后面写到了再学习学习;
def is_set(self):
这个简单,返回flag状态;

源码 2/3
    def set(self):
        """Set the internal flag to true.

        All threads waiting for it to become true are awakened. Threads
        that call wait() once the flag is true will not block at all.

        """
        with self._cond:
            self._flag = True
            self._cond.notify_all()

    def clear(self):
        """Reset the internal flag to false.

        Subsequently, threads calling wait() will block until set() is called to
        set the internal flag to true again.

        """
        with self._cond:
            self._flag = False

【注释我都不想删掉了,凑点字数23333】
def set(self):
flag首先设为True,继而释放所有线程
def clear(self):
flag设为False

源码 3/3
    def wait(self, timeout=None):
        """Block until the internal flag is true.

        If the internal flag is true on entry, return immediately. Otherwise,
        block until another thread calls set() to set the flag to true, or until
        the optional timeout occurs.

        When the timeout argument is present and not None, it should be a
        floating point number specifying a timeout for the operation in seconds
        (or fractions thereof).

        This method returns the internal flag on exit, so it will always return
        True except if a timeout is given and the operation times out.

      """
        with self._cond:
            signaled = self._flag
            if not signaled:
                signaled = self._cond.wait(timeout)
            return signaled

def wait(self, timeout=None):
先判断flag信号,只有当前状态下flag是False才会进行等待,并且释放condition一级锁(也就是实例化Event类中定义的 self._cond = Condition(Lock()) )
Event.wait()函数在被Event.set()函数唤醒之后,在类condition的wait()函数中的finally尝试恢复一级锁;set()函数在下一句代码中才会释放锁;释放之后难道一定会是finally中的语句拿到嘛?不过我倒是感觉谁拿到这个所都无所谓。。。
END

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 串行:同一个时间段只干一件事 并行:同一个时间段可以干多件事 并发 V.S. 并行并发是指一个时间段内,有几个程序...
    苏慕漓阅读 4,907评论 0 5
  • 转载自本人知乎:https://zhuanlan.zhihu.com/p/92702108 目录 1.with 2...
    甘蔗JS阅读 586评论 0 2
  • 写在前面的话 代码中的# > 表示的是输出结果 输入 使用input()函数 用法 注意input函数输出的均是字...
    FlyingLittlePG阅读 2,956评论 0 9
  • 线程 操作系统线程理论 线程概念的引入背景 进程 之前我们已经了解了操作系统中进程的概念,程序并不能单独运行,只有...
    go以恒阅读 1,686评论 0 6
  • 进程 操作系统背景知识 顾名思义,进程即正在执行的一个过程。进程是对正在运行程序的一个抽象。 进程的概念起源于操作...
    go以恒阅读 965评论 0 2