zoukankan      html  css  js  c++  java
  • 并发编程四(3) 线程同步

    Event-信号传递

    threading.Event源码的解释是这样的,

    class Event:
        """Class implementing event objects.
    
        Events manage a flag that can be set to true with the set() method and reset
        to false with the clear() method. The wait() method blocks until the flag is
        true.  The flag is initially false.
        
        """
    

    我用大白话解释一下大致意思:event是一个内部对象,他管理着一个信号,且这个信号flag一开始是false,

    set() 方法可以把flag设置成true,这时候程序继续往下执行,

    clear()方法会把flag设置成false,

    wait(timeout)方法会一直阻塞,直到收到那个为true的内部信号或者等待时间=timeout,结束等待,继续执行后面的代码

    然后我们再来看例子,就会好理解一点

    from threading import Thread
    import threading
    import time
    
    def wait_for_event(e):
        """Wait for the event to be set before doing anything"""
        print('wait_for_event: starting')
        e.wait() # 等待收到能执行信号,如果一直未收到将一直阻塞
        print('wait_for_event: e.is_set()->', e.is_set())
    
    def wait_for_event_timeout(e,t):
        """Wait t seconds and then timeout"""
        print('wait_for_event_timeout: starting')
        e.wait(t)# 等待t秒超时,此时Event的状态仍为未设置,继续执行
        print('wait_for_event_timeout: e.is_set()->', e.is_set())
        e.set()# 初始内部标志为真  想把e内部的变量从Faslse改为True,则使用e.set()
    
    if __name__ == '__main__':  # main是主线程
        e = threading.Event() #生成一个类实例
        print("begin,e.is_set()", e.is_set())
        w1 = Thread(name='block', target=wait_for_event, args=(e,))
        w1.start()
    
        #可将2改为5,看看执行结果
        w2 = Thread(name='nonblock', target=wait_for_event_timeout, args=(e,2))
        w2.start()
    
        print('main: waiting before calling Event.set()')
        time.sleep(3)
        # e.set()   #可注释此句话看效果
        #这里如果加入w1.join(),那就会等w1线程执行完毕,再打印下面这句话
        #w1.join()
        print('main: event is set')
    

    注意:

    没有线程调用set()方法,且wait也没有设置超时时间,wait最终总是会返回true,这一点很重要,不然你难以理解为什么没有线程把flag设置为true,但是wait后面的代码最终还是会执行。我为什么会知道?可以看源码

        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
    
    
    更多学习笔记移步 https://www.cnblogs.com/kknote
  • 相关阅读:
    P4127 [AHOI2009]同类分布
    区间DP
    P3146 [USACO16OPEN]248
    P1241 括号序列
    P2858 [USACO06FEB]奶牛零食Treats for the Cows
    P2602 [ZJOI2010]数字计数&P1239 计数器&P4999 烦人的数学作业
    数位DP
    jquery生成元素注册事件无效,及事件委托的使用
    Jquery ajax运用执行顺序有误怎么解决
    html页面输入框input的美化
  • 原文地址:https://www.cnblogs.com/kknote/p/14900009.html
Copyright © 2011-2022 走看看