2016-03-24 13 views
-1

私のアプリケーションは、完了までに時間がかかる複数のI/Oブロック(ネットワーク)要求を使用します。 私はマルチスレッドを使用しようとしましたが、スピードアップを引き起こすようには見えませんでした。私はそれがPythonのGILと関係があると思います。Blocking I/Oを使用したPythonマルチスレッド化

すべてのリクエストは同時に実行でき、互いに依存関係はありません。このパフォーマンスの問題を解決するにはどうすればよいですか?

私のコード

import threading 
import urllib2 
import time 
def send_request(url, count_str): 
    start_time = time.time() 
    urllib2.urlopen(url) 
    print "Request " + count_str + " took " + str(time.time() - start_time) + " started at " + str(start_time) 

count = 0 
for url in open('urllist.txt'): 
    t = threading.Thread(target=send_request, args = (url.strip(), str(count))) 
    t.start() 
    count+=1 

出力が応答するために5秒かかる私はローカルで実行しているサーバーへのurllist.txtポイントで

Request 1 took 5.0150949955 started at 1458789266.78 
Request 2 took 10.0112490654 started at 1458789266.79 
Request 0 took 15.024559021 started at 1458789266.78 
Request 3 took 20.016972065 started at 1458789266.79 

のURLです。 ご覧のように、それらはすべて同時に開始しますが、ブロックしています。

+0

私はあなたのコードを表示することができます:) – Signal

+0

@Signal updated it =)私はPythonでマルチスレッド化するのがとても新しいので、かなり間違っている可能性があります –

+0

'q.join()'はどのように返されますか?あなたのコードの中には 'Queue'を処理して' .get() 'だけを呼び出すものはありません。' .task_done() 'だけではありません。 'get_and_read_url'から何も返さないので、' None'をエンキューするだけです。最後に、私は注意します:一般的なスレッド化と特に 'Queue'では、Python 2は_bad_です。最近のPython([3.2以降](https://docs.python.org/3/whatsnew/3.2.html#multi-threading))に移行することができれば、書き直されたGILはスレッド化しても何も得られないCPUに束縛されたタスクでは、GILのオーバーヘッドだけでコアを食べる速度は大幅に遅くなりません。 – ShadowRanger

答えて

1

私は問題を再現することができません。(少数のインターネットサーバーに対してテストを行うと、すべてのリクエストはほぼ同じ時間にサービスされ、着実に増加する遅延はありません)別の問題:使用している「ローカルサーバー」がマルチスレッド化されていない可能性があります(または複数の要求を一度に処理できない可能性があります)。

独自の出力は、スレッドが並行して起動しているが、要求は順次処理されていることを示します。問題を引き起こしているGILハンドオフだった場合は、次の起動前に完了するまでに1つのスレッドが少し遅れている(1つのスレッドはいくつかの作業を完了し、次にもう1つはもっとやるなど) 。これにより、サーバー側で問題が発生し、サーバーは追加接続を処理する前に完了要求を処理します。

精神的なデバッグで刺し傷をとると、サーバコードに睡眠を追加することで、おそらくacceptの返品後に、サービスを提供するスレッドを開始する前に、5秒のリクエスト時間を実装しましたか?または、サーバー上でスレッドを使用しないでください。

+0

これはそれだった。私が稼働していたローカルサーバーは、マルチスレッドを有効にしておらず、応答でブロックしていました。 Pythonの問題ではなく、パフォーマンスをテストするのに実際に問題があったので、質問を閉じるか、少なくとも名前を変更する必要がありますか? –

+0

@tt_Gantz:現状では、同じ理由で誰かが正当な理由で正当に尋ねるかもしれないという質問をしているので、私はそれを閉じないだろう。自分自身の問題。 – ShadowRanger

-1

Pythonスレッドが遅いです! Pythonには、内部へのアクセスをシリアライズするためにmutexを使用するGIL(Global Interpreter Lock)があります。 GILを持たないJythonを見て、マルチプロセッサシステムを完全に活用することができます。

+0

OPは質問にGILが言及していることを認識しています。スレッドはI/Oバインドされている必要があります。通常、I/Oをブロックする並列タスクを調整するためのスレッディングは正常です。 「GILは悪いのでスレッドを使用することは決してありません」は非常に単純化されており、何も追加しません。そして、Jythonの恐ろしいサポートが(言語仕様より5年以上遅れて)どれほどひどいことを考えれば、私の最初の勧告ではないでしょう。 – ShadowRanger

関連する問題