2012-01-05 10 views
0

IBM developer sourcesのスレッディングについて読んだところ、次の例が見つかりました。Pythonでのスレッドの理解: `run()`に処理されたデータを返す方法を教えてください。

一般的に私は重要なことを除いて、ここで何が起こるのか理解しています。この作業はrun()機能で実行されているようです。この例では、run()は、行と信号をキューに出力するだけで、ジョブが完了します。

処理されたデータを返さなければならない場合はどうすればよいですか?私はそれをグローバル変数にキャッシュすることを考えましたが、後でこの変数にアクセスすることになりましたが、これは正しい方法ではないようです。

アドバイスはありますか?私の直感は右self.queue.task_done()run()return processed_dataを追加するために私に語っが、そのリターンをキャッチする場所run()が呼び出される場合、それは私には明らかにされていませんので、私は、把握することはできません。

おそらく、私はclearify必要があります。

#!/usr/bin/env python 
import Queue 
import threading 
import urllib2 
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): 
    """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(1024) 

      #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(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() 

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

答えて

3

あなたはrunから値を返す、そしてどのような場合に使用すると、1つの値を処理した後で、すべて返すようにしたくないので、各スレッドで処理するために、通常、複数の項目があることはできません(参照各スレッドのループはwhile)。

私は結果を返すために別のキューを使用することになり、次のいずれか

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

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

      #grabs urls of hosts and saves first 1024 bytes of page 
      url = urllib2.urlopen(host) 
      out_queue.put(url.read(1024)) 

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

... 

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

    #don't have to wait until everything has been processed if we don't want to 

    for _ in range(len(hosts)): 
     first_1k = out_queue.get() 
     print first_1k 

または同じキューに結果を格納:

class WorkItem(object): 
    def __init__(self, host): 
     self.host = host 

class ThreadUrl(threading.Thread): 
    ... 
    def run(self): 
     while True: 
      #grabs host from queue 
      work_item = self.queue.get() 
      host = work_item.host 

      #grabs urls of hosts and saves first 1024 bytes of page 
      url = urllib2.urlopen(host) 
      work_item.first_1k = url.read(1024) 

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

... 

def main(): 
    ... 
    #populate queue with data 
    work_items = [WorkItem(host) for host in hosts] 
    for item in work_items: 
     queue.put(item) 

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

    for item in work_items: 
     print item.first_1k 
0

は、キュー方式を使用しての問題点は次のとおりです。順序スレッドが完了するスレッドはランダムです。したがって、キューアイテムは必ずしもその特定の位置の結果を反映していない可能性があります。 この例では、google.comがyahoo.comより前に完了すると、キューにはyahooデータの前にgoogleデータがあるため、検索すると結果が正しくありません。

関連する問題