乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      python 之美

       java_laq小館 2014-11-18

      Python之美[從菜鳥到高手]--threading daemon線程原理解讀

      分類: python 823人閱讀 評(píng)論(0) 收藏 舉報(bào)

      事情的起因是我在看下面一段代碼遇到的疑惑,明明是while True,為什么代碼沒有死循環(huán)??

      1. class D(threading.Thread):  
      2.     def __init__(self, queue):  
      3.         threading.Thread.__init__(self)  
      4.         self.queue = queue  
      5.     def run(self):  
      6.         while  True:  
      7.             url = self.queue.get()  
      8.             self.download_file(url)  
      9.             self.queue.task_done()  
      10.   
      11.     def download_file(self, url):  
      12.         h = urllib2.urlopen(url)  
      13.         f = os.path.basename(url)+'.html'  
      14.         with open(f,'wb') as f:  
      15.             while  True:  
      16.                 c = h.read(1024)  
      17.                 if not c:  
      18.                     break  
      19.                 f.write(c)  
      20.   
      21. if __name__ == "__main__":  
      22.     urls= ['http://www.baidu.com','http://www.sina.com']  
      23.     queue = Queue.Queue()  
      24.     for i in range(5):  
      25.         t = D(queue)  
      26.         t.setDaemon(True)  
      27.         t.start()  
      28.   
      29.     for u in urls:  
      30.         queue.put(u)  
      31.   
      32.     queue.join()  

      之前一直簡(jiǎn)單認(rèn)為setDaemon就是設(shè)置為后臺(tái)線程而已,沒有進(jìn)一步去挖掘里面的含義。

      可問題的關(guān)鍵就是setDaemon,在底層的thread模塊中,只要主線程結(jié)束了,所有的其它線程都會(huì)結(jié)束,這很明顯,主線程結(jié)束python將銷毀運(yùn)行時(shí)環(huán)境,主線程肯定會(huì)被結(jié)束。

      threading模塊的線程setDaemon就是為了解決這個(gè)問題的,如果setDaemon(True),那么和之前一樣,主線程結(jié)束,所有子線程都將結(jié)束。如果setDaemon(False),主線程將等待該線程結(jié)束,等同于你調(diào)用線程的join方法。

      所以如果將上面的setDaemon注釋和修改為False,那么程序?qū)⑺姥h(huán)。

      其實(shí)我們并不推薦上面的做法,上面做法有點(diǎn)線程池的味道,但如果你看過一些python的線程池實(shí)現(xiàn),while True

      循環(huán)中肯定有檢測(cè)退出語(yǔ)句,因?yàn)樵趐ython的世界里言明比隱晦更加pythonic。但很不幸的是,上面的代碼就來

      自與<<編寫高質(zhì)量代碼:改善Python程序的91個(gè)建議>>,我并沒有噴這本書,但我覺得代碼舉例的確有待商榷。

      你可能好奇,setDaemon(False)是如何等同于線程join的呢?,不急,且聽我慢慢道來。

      未解決這個(gè)問題,threading模塊引入了_MainThread對(duì)象

      1. # Special thread class to represent the main thread  
      2. # This is garbage collected through an exit handler  
      3.   
      4. class _MainThread(Thread):  
      5.   
      6.     def __init__(self):  
      7.         Thread.__init__(self, name="MainThread")  
      8.         self._Thread__started.set()  
      9.         self._set_ident()  
      10.         with _active_limbo_lock:  
      11.             _active[_get_ident()] = self  
      12.   
      13.     def _set_daemon(self):  
      14.         return False  
      15.   
      16.     def _exitfunc(self):  
      17.         self._Thread__stop()  
      18.         t = _pickSomeNonDaemonThread()  
      19.         if t:  
      20.             if __debug__:  
      21.                 self._note("%s: waiting for other threads"self)  
      22.         while t:  
      23.             t.join()  
      24.             t = _pickSomeNonDaemonThread()  
      25.         if __debug__:  
      26.             self._note("%s: exiting"self)  
      27.         self._Thread__delete()  
      28.   
      29. def _pickSomeNonDaemonThread():  
      30.     for t in enumerate():  
      31.         if not t.daemon and t.is_alive():  
      32.             return t  
      33.     return None  
      34.   
      35. # Create the main thread object,  
      36. # and make it available for the interpreter  
      37. # (Py_Main) as threading._shutdown.  
      38.   
      39. _shutdown = _MainThread()._exitfunc  
      其實(shí)_MainThread并沒有干什么事,唯一的貢獻(xiàn)就是在threading模塊導(dǎo)入時(shí)創(chuàng)建了一個(gè)實(shí)例,并將_exitfunc
      賦值給_shutdown函數(shù)。_exitfunc將收集所有非daemon且alive的線程,并調(diào)用線程的join方法。哦,原來是

      _MainThread悄悄的在幕后奮斗著,剩下的問題就是誰(shuí)調(diào)用_shutdown函數(shù)的呢?

      當(dāng)python要銷毀運(yùn)行時(shí)之前肯定會(huì)調(diào)用,所以打開pythonrun.c,你會(huì)發(fā)現(xiàn)如下函數(shù)

      1. /* Wait until threading._shutdown completes, provided 
      2.    the threading module was imported in the first place. 
      3.    The shutdown routine will wait until all non-daemon 
      4.    "threading" threads have completed. */  
      5. static void  
      6. wait_for_thread_shutdown(void)  
      7. {  
      8. #ifdef WITH_THREAD  
      9.     PyObject *result;  
      10.     PyThreadState *tstate = PyThreadState_GET();  
      11.     PyObject *threading = PyMapping_GetItemString(tstate->interp->modules,  
      12.                                                   "threading");  
      13.     if (threading == NULL) {  
      14.         /* threading not imported */  
      15.         PyErr_Clear();  
      16.         return;  
      17.     }  
      18.     result = PyObject_CallMethod(threading, "_shutdown""");  
      19.     if (result == NULL)  
      20.         PyErr_WriteUnraisable(threading);  
      21.     else  
      22.         Py_DECREF(result);  
      23.     Py_DECREF(threading);  
      24. #endif  
      25. }  
      原來是這家伙在搞鬼,漲見識(shí)了,原來在C中還有調(diào)用py代碼的需求啊。沒辦法啊,誰(shuí)讓threading模塊是純py
      代碼呢?。?!

      來自:http://blog.csdn.net/yueguanghaidao/article/details/40088431

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多