2012-12-05 158 views
1

我在閱讀一篇關於使用隊列的Python多線程的文章,並且有一個基本問題。使用隊列的Python多線程

基於print stmt,5個線程按預期啓動。那麼,隊列是如何工作的?

1.線程是最初啓動的,當隊列填充項時是否重新啓動並開始處理該項? 2.如果我們使用隊列系統和線程處理隊列中的每個項目,那麼性能有何提高?它與串行處理不相似,即: 1除以1.

import Queue 
import threading 
import urllib2 
import datetime 
import time 

hosts = ["http://yahoo.com", "http://google.com", "http://amazon.com", 
"http://ibm.com", "http://apple.com"] 

queue = Queue.Queue() 

class ThreadUrl(threading.Thread): 

    def __init__(self, queue): 
    threading.Thread.__init__(self) 
    print 'threads are created' 
    self.queue = queue 

    def run(self): 
    while True: 
     #grabs host from queue 
     print 'thread startting to run' 
     now = datetime.datetime.now() 

     host = self.queue.get() 

     #grabs urls of hosts and prints first 1024 bytes of page 
     url = urllib2.urlopen(host) 
     print 'host=%s ,threadname=%s' % (host,self.getName()) 
     print url.read(20) 

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

start = time.time() 
if __name__ == '__main__': 

    #spawn a pool of threads, and pass them queue instance 
    print 'program start' 
    for i in range(5): 

     t = ThreadUrl(queue) 
     t.setDaemon(True) 
     t.start() 

#populate queue with data 
    for host in hosts: 
     queue.put(host) 

#wait on the queue until everything has been processed  
    queue.join() 


    print "Elapsed Time: %s" % (time.time() - start) 

回答

1

隊列與列表容器類似,但具有內部鎖定以使其成爲線程安全的數據通信方式。

當你開始你的所有線程時會發生什麼,它們都會在self.queue.get()呼叫上阻塞,等待從隊列中拉出一個項目。從主線程將項目放入隊列時,其中一個線程將被解鎖並接收項目。然後它可以繼續處理它直到完成並返回到阻塞狀態。

您的所有線程都可以併發運行,因爲它們都能夠從隊列中接收項目。這是你會看到你的表現有所提高的地方。如果urlopenread在一個線程中花費時間並且它正在IO上等待,這意味着另一個線程可以工作。隊列對象作業只是簡單地管理鎖定訪問,並將項目彈出給調用者。