<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          除了 time.sleep,還可以這樣讓代碼暫停

          共 2073字,需瀏覽 5分鐘

           ·

          2021-01-17 02:48


          大家好,歡迎來(lái)到Crossin的編程教室!

          我們知道,在 Python 里面可以使用time.sleep來(lái)讓代碼暫停一段時(shí)間,例如:

          import?time

          print('...部分代碼...')
          time.sleep(5)
          print('...剩下的代碼...')

          程序首先打印出...部分代碼...,然后等待5秒鐘,再打印出...剩下的代碼...

          現(xiàn)在大家想一想,有沒(méi)有什么辦法,在不使用time.sleep的情況下,讓程序暫停5秒?

          你可能會(huì)說(shuō),用requests訪問(wèn)一個(gè)延遲5秒的網(wǎng)址、或者用遞歸版算法計(jì)算斐波那契數(shù)列第36位……這些奇技淫巧。

          不過(guò)今天我說(shuō)的,是另外一個(gè)東西,threading模塊里面的Event

          我們來(lái)看看它的用法:

          import?threading

          event?=?threading.Event()
          print('...部分代碼...')
          event.wait(5)
          print('...剩下的代碼...')

          這樣一來(lái),程序首先打印出...部分代碼...,然后等待5秒鐘,再打印出...剩下的代碼...。

          功能看起來(lái)跟time.sleep沒(méi)什么區(qū)別,那為什么我要特別提到它呢?因?yàn)樵诙嗑€程里面,它比time.sleep更有用。我們來(lái)看一個(gè)例子:

          import?threading

          class?Checker(threading.Thread):
          ????def?__init__(self,?event):
          ????????super().__init__()
          ????????self.event?=?event

          ????def?run(self):
          ????????while?not?self.event.is_set():
          ????????????print('檢查?redis?是否有數(shù)據(jù)')
          ????????????time.sleep(60)

          trigger_async_task()
          event?=?threading.Event()
          checker?=?Checker(event)
          checker.start()
          if?user_cancel_task():
          ????event.set()

          我來(lái)解釋一下這段代碼的意思。在主線程里面,我調(diào)用trigger_async_task()觸發(fā)了一個(gè)異步任務(wù)。這個(gè)任務(wù)多久完成我并不清楚。但是這個(gè)任務(wù)完成以后,它會(huì)往 Redis 里面發(fā)送一條消息,只要 Redis 有這個(gè)消息了,我就知道它完成了。所以我要?jiǎng)?chuàng)建一個(gè) checker 子線程,每60秒去 Redis里面檢查任務(wù)是否完成。如果沒(méi)有完成,就暫停60秒,然后再檢查。

          但某些情況下,我不需要等待了,例如用戶主動(dòng)取消了任務(wù)。這個(gè)時(shí)候,我就想提前結(jié)束這個(gè) checker 子線程。

          但是我們知道,線程是不能從外面主動(dòng)殺死的,只能讓它自己退出。所以當(dāng)我執(zhí)行event.set()后,子線程里面self.event.is_set()就會(huì)返回 False,于是這個(gè)循環(huán)就不會(huì)繼續(xù)執(zhí)行了。

          可是,如果某一輪循環(huán)剛剛開始,我在主線程里面調(diào)用了event.set()。此時(shí),子線程還在time.sleep中,那么子線程需要等待60秒才會(huì)退出。

          但如果我修改一下代碼,使用self.event.wait(60)

          import?threading

          class?Checker(threading.Thread):
          ????def?__init__(self,?event):
          ????????super().__init__()
          ????????self.event?=?event

          ????def?run(self):
          ????????while?not?self.event.is_set():
          ????????????print('檢查?redis?是否有數(shù)據(jù)')
          ????????????self.event.wait(60)

          trigger_task()
          event?=?threading.Event()
          checker?=?Checker(event)
          checker.start()
          if?user_cancel_task():
          ????event.set()

          那么,即便self.event.wait(60)剛剛開始阻塞,只要我在主線程中執(zhí)行了event.set(),子線程里面的阻塞立刻就會(huì)結(jié)束。于是子線程立刻就會(huì)結(jié)束。不需要再白白等待60秒。

          并且,event.wait()這個(gè)函數(shù)在底層是使用 C 語(yǔ)言實(shí)現(xiàn)的,不受 GIL 鎖的干擾。

          總結(jié)一下簡(jiǎn)單來(lái)說(shuō)就是:如果你想在多線程時(shí)更靈活地控制代碼運(yùn)行等待,那么用event.wait要比time.sleep更合適。

          作者:kingname
          來(lái)源:未聞Code


          _往期文章推薦_

          python中的時(shí)間處理大總結(jié)




          瀏覽 50
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  3级片免费网站免费播放无码久久 | 有在线操逼的网站吗 | 一区二区三区国产 | 色婷婷综合激情网 | 国内精品久久久久久久久久 |