2016-11-23 8 views
0

私は、ある関数がキューに関数を追加し、同時にいくつかのヘルパースレッドが空になるまでキューからポップするようなマルチスレッドルーチンを設計しています。理論的には、これは単一のスレッド実装よりもはるかに高速でなければなりませんが、実際のアプリケーションとこの質問のために設計したおもちゃの例ではそうではありません。理由は、Queueオブジェクト(これはPythonのドキュメントに従ってスレッドセーフです)との同期問題ですが、それは唯一の推測だと思います。一般的な最適化の助けをいただければ幸いです!マルチスレッドキュー操作が単一スレッドより高速ではない

そしておもちゃの例のコード:以下

from Queue import Queue 
import time 
queue = Queue(maxsize=0) 
counter = [] 

#called by an external main method, adds and removes from global queue in single thread 
def single_thread(): 
    fillit() 
    time_origin = "%.10f" % time.time() 
    while not queue.empty(): 
     queue.get() 
    time_end = "%.10f" % time.time() 
    time_t = float(time_end) - float(time_origin) 
    print "time of single threaded implementation: " + str(time_t) +"\n" 

#called by an external main method; adds to queue and removes from queue in multiple threads 
def multi_thread(): 
    fillit() 
    time_origin = "%.10f" % time.time() 
    spawn_threads(4) 
    time_end = "%.10f" % time.time() 
    time_t = float(time_end) - float(time_origin) 
    print "time of multi threaded implementation: " + str(time_t) +"\n" 

#Fills up the queue with 2^19 elements 
def fillit(): 
    for i in range(2 ** 19): 
     queue.put(i) 

#Spawns n helper threads to help empty the queue 
def spawn_threads(num_threads): 
    for i in range(num_threads): 
     counter.append(0) 
     thread = myThread(i, "Thread-" + str(i)) 
     thread.setDaemon(True) 
     thread.start() 
    while not queue.empty(): 
     continue 
    print "done with threads " + str(counter) +" elements removed!" 

#THREADING SUPPORT CODE 
import threading 

class myThread (threading.Thread): 
    def __init__(self, threadID, name): 
     threading.Thread.__init__(self) 
     self.threadID = threadID 
     self.name = name 
    def run(self): #each thread continues to empty the queue while it still has elements 
     while not queue.empty(): 
      queue.get() 
      global counter 
      counter[self.threadID] +=1 

結果:あなたはここで見ている何

time of single threaded implementation: 1.51300001144 

done with threads [131077, 131070, 131071, 131070] elements removed! 
time of multi threaded implementation: 7.77100014687 
+0

開始時間と終了時間を文字列にキャストしているのですが、時間を計算するために浮動小数点にキャストするのはなぜですか? –

+0

@BrendanAbelあなたが言うことは、開始時にキャスティングに有効です。それは確かに私が経験している減速に関連していません。 – jaykk128

答えて

0

はアクションでPythonのGILです。 GILは、プロセスごとに1つのスレッドのみがPythonコードを実行することを保証します。これにより、高速ではなくIOバインドされていないマルチスレッドタスクが遅くなります。this linkを参照してください。実際の並行処理を行う場合は、マルチスレッドの代わりにマルチプロセッシングを見てください。共用状態の欠如とプロセスのスピンアップがよりコストがかかるため、マルチプロセッシングにはオーバーヘッドが増えます。

+0

Pycharm(私が使っているIDE)は--multiprocフラグでコンパイルします。これは複数のプロセスにわたるスレッドに影響を及ぼしますか、それともGILは依然として制限要因ですか?私が望む行動を得るためにどのようなモジュール/プラットフォームを提案しますか? – jaykk128

+0

Pythonは本当のマルチスレッド化ができませんので、あなたが望む動作を得るプラットフォームはありません –

関連する問題