28

Python でスレッド化を使用して多くの Web ページをダウンロードしたかったので、Web サイトの 1 つでキューを使用する次のコードを実行しました。

無限 while ループを配置します。各スレッドは、すべてが完了するまで終了することなく実行されますか? 私は何かが欠けていますか?

#!/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)
4

3 に答える 3

20

スレッドをスレッドに設定するとdaemon、メインが終了したときにスレッドが終了します。queueしかし、そうです、あなたのスレッドは、それがブロックするものがある限り継続的に実行されるという点で正しいです。

ドキュメントでは、この詳細について説明していますQueue docs

python Threading documentation もそのdaemon部分を説明しています。

生きている非デーモン スレッドがなくなると、Python プログラム全体が終了します。

そのため、キューが空になりqueue.join、インタープリターが終了したときに再開すると、スレッドは終了します。

編集: のデフォルト動作の修正Queue

于 2012-11-20T20:25:38.190 に答える
8

あなたのスクリプトは私にとってはうまく機能するので、何が起こっているのかをよりよく理解できるように尋ねていると思います。はい、サブクラスは各スレッドを無限ループに入れ、何かがキューに入れられるのを待ちます。何かが見つかると、それをつかみ、その役割を果たします。次に、重要な部分として、queue.task_done で完了したことをキューに通知し、キュー内の別のアイテムの待機を再開します。

これがすべてワーカー スレッドで行われている間、メイン スレッドはキュー内のすべてのタスクが完了するまで待機 (結合) します。これは、スレッドがキュー内のメッセージと同じ回数 queue.task_done フラグを送信したときです。待ち行列 。その時点で、メイン スレッドは終了し、終了します。これらはデーモン スレッドであるため、それらも閉じます。

これはクールなもの、スレッドとキューです。これは、Python の優れた点の 1 つです。Python でのスレッド化が GIL などでどのように台無しにされているかについて、あらゆる種類のことを聞くでしょう。しかし、それらをどこで使用するか (この場合はネットワーク I/O の場合など) を知っていれば、実際に処理速度が向上します。一般的なルールは、I/O バウンドの場合は、スレッドを試してテストすることです。あなたがCPUに縛られているなら、スレッドはおそらく良い考えではありません.代わりにプロセスを試してみてください.

幸運を、

マイク

于 2012-11-20T20:33:16.497 に答える
-2

Queueこの場合は必要ないと思います。のみを使用Thread

import threading, urllib2, time

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

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

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

start = time.time()
def main():
    #spawn a pool of threads
    for i in range(len(hosts)):
        t = ThreadUrl(hosts[i])
        t.start()

main()
print "Elapsed Time: %s" % (time.time() - start)
于 2012-11-20T20:30:31.050 に答える