2012-03-07 20 views
1

Pythonプログラムでは、スレッドモジュールに基づいて2つのスレッドが必要です。スレッド#1はいくつかのデータを生成してバッファに入れ、スレッド#2はバッファ内のデータを処理することになっています。スレッドモジュールを使ってPythonでスレッドを実装する

だから私の擬似コードは、このようなものです: スレッド1:

Thread#1 
while True: 
    Generate_Some_Data() 
    while flag==1: 
     pass() 
    Buffer_Address=Write_It_To_Buffer() 
    flag=1 


Thread#2 
while True: 
    while flag==0: 
     pass() 
    Process_Data(Buffer_Address) 
    flag=0 

(私たちは、変数「フラグ」へのアクセスは、適切なロックで霧化されると仮定しましょう。)

私が知っているスレッディングモジュールいます同時ではありません。基本的に、これは、スレッドのいずれかが外部条件(file-ioやtime.sleepなど)でブロックされない限り、両方のスレッドがタスクに関係なく合計プロセス時間を共有することを意味します。したがって、私の理解によれば、上記の構成では、「フラグ」ループでは総処理時間の約半分が無駄になります。

だから、ここは私の質問です:

  1. は、私は右の私の上記見越し/スレッディングモジュールの理解のですか? 「フラグ」がループしている間に、合計プロセス時間の半分が無駄になりますか?

  2. (私が正しければ) "while flag"ループを完全に取り除く方法はありますか?私はlock.acquire()メソッドでスレッドをスリープさせることができる別の構造体を見つけようとしましたが、%100の安全な方法を理解できませんでした。 (1スレッドrelasesがロックすると、同じスレッドが再びそれを取得する前に、他のスレッドがそれを取得することはquaranteeはありません)

答えて

3

the Queue moduleは何が必要であるように聞こえます。

これにより、ブロックするFIFOキューが得られます。コンシューマスレッドがキューから何かを取得するたびに、何もない場合は何かが利用可能になるまでブロックされ、プロデューサスレッドは何かを生成するための時間を与えます。

プロデューサスレッドがすべての計算サイクルを煩わせるのであれば、キューのサイズに制限を設けることができます。キューがいっぱいで、プロデューサスレッドに何かが追加されている場合、コンシューマスレッドが何かを取り出すまでブロックされます。

import Queue 
q = Queue.Queue() 

# Producer thread 
while True: 
    data = generate_some_data() 
    q.put(data) 

# Consumer thread 
while True: 
    data = q.get() 
    process_data(data) 
+0

私もフォローアップの質問があります:

は、ここではいくつかの擬似コードです。 python Queue'sは、コンシューマ・スレッドが同一であることを前提としたセマフォ・コンセプトの実装です。データ型に基づいてキュー内のデータを処理するはずの2つのコンシューマ・スレッドがあるとします。たとえば、データのタイプが「int」の場合、コンシューマ1はデータを処理する必要があるとします。それが「フロート」の場合、消費者2はそれを処理しなければならない。しかし、それが "文字列"の場合、消費者1も2もデータを処理する必要はありません。そのような問題を実装するのに役立つプログラミングパラダイムはありますか? – tantuni

+1

@ user460153私は単純に各消費者のための別のキューを作成します。 – Taymon

+0

"条件変数"はこの問題のより良いパラダイムだと思います。すべてのコンシューマスレッドは、メインスレッドがシグナルを出すのを待ちます。メインスレッドによって通知された後、各コンシューマスレッドはデータ型をチェックし、データを処理するかスリープ状態を続けるかを決定します。 – tantuni

関連する問題