2011-08-19 8 views
0

誰でもこのコードがスレッドを開始した後にキューを生成する理由を教えてもらえますか?基本的に、キューはforループの後に生成されますが、ThreadUrlクラスではすでにqueue.get()メソッドが使用されています。これはどのように作動しますか?まだ生成されていないキューから値を取得するにはどうすればよいですか?python multithreading question

for i in range(5): 
    t = ThreadUrl(queue, out_queue) 
    t.setDaemon(True) 
    t.start() 

# This is what confuses me! Shouldn't it be above the for loop?? 
for host in hosts: 
    queue.put(host) 

for i in range(5): 
    dt = DatamineThread(out_queue) 
    dt.setDaemon(True) 
    dt.start() 

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

は、ここではいくつかの要素になるまでスレッドを実行

import Queue 
import threading 
import urllib2 
import time 
from BeautifulSoup import BeautifulSoup 

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

queue = Queue.Queue() 
out_queue = Queue.Queue() 

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

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

      #grabs urls of hosts and then grabs chunk of webpage 
      url = urllib2.urlopen(host) 
      chunk = url.read() 

      #place chunk into out queue 
      self.out_queue.put(chunk) 

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

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

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

      #parse the chunk 
      soup = BeautifulSoup(chunk) 
      print soup.findAll(['title']) 

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

start = time.time() 
def main(): 

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

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

    for i in range(5): 
     dt = DatamineThread(out_queue) 
     dt.setDaemon(True) 
     dt.start() 


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

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

答えて

6

ラインhost = self.queue.get()ブロックがqueueに表示され、完全なソースです。

ので

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

は、キュー内の任意の要素を待っている5つのスレッドを作成します。

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

がキューに入ります。このスレッドが処理を開始した後。

+0

ありがとうございます!ループの前とループの後にキューを入れることに違いはありますか? – Shaokan

+1

最初のループ(ThreadUrlsを作成する)の後、6つのスレッドがあります。あなたのメインスレッドがキューにフィードします。他のスレッドはそのキューから消費し、キューが空の場合はキューに何かが表示されるまでブロックします。 スレッドを作成する前にキューを作成すると、最初のスレッドは5つのジョブを表示し、2番目のスレッドは4などを表示します。各スレッドは直ちにキューから消費できます。 スレッドを開始した後にキューにデータを挿入すると、キューが空であるため、すべてのスレッドが最初にブロックされます。要素を追加した後でのみ、1つのスレッドがキューから取得します。 –

+0

@クイタン、説明をありがとう!だから基本的には、スレッドは常にプログラムが正常に動作している間に待ち行列内にある可能性のある項目を待つので、最初と最後に待ち行列にデータを入れることに違いはありませんか? – Shaokan