2009-05-20 7 views
6

私は、同期ポイントに達するまで、xスレッドが待機する必要がある問題があります。私の解決策は同期する必要があるときに各スレッド関数によって呼び出される以下のsynchroniseメソッドを使用します。Pythonで複数のスレッドを同期する

これを行うより良い方法はありますか?

thread_count = 0 
semaphore = threading.Semaphore() 
event = threading.Event() 

def synchronise(count): 
    """ All calls to this method will block until the last (count) call is made """ 
    with semaphore: 
     thread_count += 1 
     if thread_count == count: 
      event.set() 

    event.wait() 

def threaded_function(): 
    # Do something 

    # Block until 4 threads have reached this point 
    synchronise(4) 

    # Continue doing something else 

答えて

1

スレッドを同期する方法はたくさんあります。たくさんの。

同期化に加えて、次のようなことができます。

  1. タスクを2つのステップに分割して、同期ポイントを囲んでください。事前同期ステップを実行するスレッドを開始します。次に、「結合」を使用して、すべてのスレッドがステップ1を終了するまで待ちます。同期後のステップを実行する新しいスレッドを開始します。私はこれを好む、同期するより。

  2. キューを作成します。同期ロックを獲得する。すべてのスレッドを開始します。各スレッドは、キューにエントリを入れ、同期ロックを待機します。 「メイン」スレッドは、キューから項目をデキューするループ内に位置します。すべてのスレッドがアイテムをキューに入れると、「メイン」スレッドは同期ロックを解除します。他のすべてのスレッドは自由に再実行できます。

スレッド間同期には、すべてのプロセス間通信(IPC)手法が使用できます。

+0

をその努力を2つのタスクに分割します。この制約がなければ、あなたのソリューションは理想的です。 –

+0

スレッドはすべて同じメモリを共有しているので、スレッドを2つのステップに分解できない理由は明確ではありません。同期化前に作成された情報は、新しいスレッドが同期後に使用するために完全に利用可能でなければなりません。 –

2

barrier」という機能があります。 (残念なことに、その用語にはスレッディングについての2つの意味がありますので、Googleの場合は、「memory barriers」という話を無視してください)。

あなたのコードは非常に妥当です。シンプルで安全です。

私はPython用のバリアの "標準"実装を見つけることができませんでしたので、コードを使い続けることをお勧めします。

2

バリアは障壁を使用してのas of Python 3.2

例実施されていることに注意してください:私はあなたの最初の提案を検討したが、スレッドをせずに同期する前に、同期作業後の両方やって持ってする必要があった

from threading import Barrier, Thread 

def get_votes(site): 
    ballots = conduct_election(site) 
    all_polls_closed.wait()  # do not count until all polls are closed 
    totals = summarize(ballots) 
    publish(site, totals) 

all_polls_closed = Barrier(len(sites)) 
for site in sites: 
    Thread(target=get_votes, args=(site,)).start() 
関連する問題