2009-09-21 102 views
3

我遇到了幾個使用線程模塊(使用Python 2.6)管理線程的示例。線程中的流程控制。線程

我想知道的是,這個例子是如何調用「run」方法和地方的。我沒有看到它的任何地方。 ThreadUrl類在main()函數中實例化爲「t」,這就是我通常希望代碼啓動「run」方法的地方。

也許這不是使用線程的首選方式?請賜教:

#!/usr/bin/env python 

import Queue 
import time 
import urllib2 
import threading 
import datetime 

hosts = ["http://example.com/", "http://www.google.com"] 

queue = Queue.Queue() 

class ThreadUrl(threading.Thread): 
    """Threaded Url Grab""" 
    def __init__(self, queue): 
      threading.Thread.__init__(self) 
      self.queue = queue 

    def run(self): 
      while True: 
        #grabs host from queue 
        host = self.queue.get() 

        #grabs urls of hosts and prints first 1024 bytes of page 
        url = urllib2.urlopen(host) 
        print url.read(10) 

        #signals to queue job is done 
        self.queue.task_done() 

start = time.time() 

def main(): 

    #spawn a pool of threads, and pass them queue instance 
    for i in range(1): 
      t = ThreadUrl(queue) 
      t.setDaemon(True) 
      t.start() 

      for host in hosts: 
        queue.put(host) 

    queue.join() 
main() 
print "Elapsed time: %s" % (time.time() - start) 

回答

7

pydoc

Thread.start()

啓動線程的活動。

每個線程對象最多隻能調用一次。它安排 對象的run()方法在 中被調用一個單獨的控制線程。

如果在同一線程對象上調用一次超過 ,此方法將引發RuntimeException。

認爲蟒蛇Thread對象的方式是,他們採取的是同步寫入Python代碼(無論是在run方法或通過target參數),並在知道C代碼包起來如何某些塊使其異步運行。這樣做的好處在於,你可以像不透明的方法那樣對待start:除非你用C重寫課程,否則你沒有任何業務覆蓋它,但是你可以非常具體地處理run。例如,如果您想要同步測試線程的邏輯,這會很有用。您所需要的只是撥打t.run(),它將像其他任何方法一樣執行。

+0

感謝您的好答案,我沒有看到文檔。 – alfredodeza 2009-09-21 17:17:08

4

方法的run()是由「threading.Thread」(谷歌繼承和多態的概念OOP)的所謂的幕後。調用將在t.start()調用後立即完成。

如果您有權訪問threading.py(在python文件夾中找到它)。你會看到一個類名Thread。在那個類中,有一個叫做「start()」的方法。 start()稱爲'_start_new_thread(self。_ _ bootstrap,())'一個低級線程啓動,它將運行一個叫做'_ _ bootstrap()'的包裝方法。 '_ _ bootstrap()',然後叫做'_ _ bootstrap_inner()',在做更多準備之前,最後調用'run()'。

閱讀本文,您可以學到很多東西。 :d

+0

+1這很神奇。如果您要使用線程,請嘗試使用PyQt線程,因爲它們更加優化並允許信號/插槽跨線程進行通信。 – Chazadanga 2009-09-21 15:06:17

0

t.start()會在操作系統一個新的線程,當該線程開始它會調用線程的run()方法(或不同的功能,如果你在Thread構造提供target