Pythonのバリア(Barrier)オブジェクトとは?スレッド同期の基本を解説
Pythonのバリア(Barrier)オブジェクトとは
バリア(Barrier)は、Pythonが提供するスレッド同期手法のひとつです。単一または複数のスレッドが、処理の流れの中の特定の時点で互いに待ち合わせ、参加スレッド全員が揃ったところで一斉に先へ進むための仕組みを提供します。
バリアオブジェクトを作成するには、threading.Barrierを使用します。
threading.Barrier(parties, action = None, timeout = None)
コンストラクタの引数
- parties:待ち合わせるスレッドの数。
- action:スレッドが解放される際に、いずれか1つのスレッドによって呼び出される関数。
- timeout:デフォルトのタイムアウト値。
wait()に個別のタイムアウト値が指定されなかった場合に、この値が使用されます。
Barrierクラスの主な属性とメソッド
| No. | メソッド/属性と説明 |
|---|---|
| 1 | parties 共通のバリアポイントに到達するために必要なスレッドの数。 |
| 2 | n_waiting 現在バリアポイントで待機中のスレッドの数。 |
| 3 | broken ブール値。バリアが壊れた(broken)状態であればTrue、そうでなければFalse。 |
| 4 | wait(timeout = None) バリアを通過し、参加するすべてのスレッドがこのメソッドを呼び出すまで、呼び出し元のスレッドを一時停止させます。 timeout引数が指定されNoneでない場合は、操作のタイムアウト時間を秒単位(小数も可)で表す浮動小数点数である必要があります。タイムアウトが発生した場合、バリアは壊れた状態になり、 BrokenBarrierErrorが発生します。 |
| 5 | reset() バリアをデフォルトの状態(空の状態)に戻します。このとき待機中だったスレッドには、 BrokenBarrierErrorが送られます。 |
| 6 | abort() バリアを強制的に壊れた状態にします。これにより、実行中のすべてのスレッドや、その後の wait()呼び出しはBrokenBarrierErrorで失敗します。 |
バリアの使用例
以下は、4つのスレッドがバリアで待ち合わせる簡単なサンプルコードです。
barrierThread.py
from random import randrange
from threading import Barrier, Thread
from time import ctime, sleep
num = 4
# 4つのスレッドがこのバリアを通過すると、全員が解放されます。
b = Barrier(num)
names = ['India', 'Japan', 'USA', 'China']
def player():
name = names.pop()
sleep(randrange(2, 5))
print('%s reached the barrier at: %s \n' % (name, ctime()))
b.wait()
threads = []
print("Race starts now…")
for i in range(num):
threads.append(Thread(target=player))
threads[-1].start()
"""
以下のループにより、メインスクリプトが先へ進む前に
各スレッドの完了を待機できるようになります。
"""
for thread in threads:
thread.join()
print("All Reached Barrier Point!")
実行結果
Race starts now…
India reached the barrier at: Fri Jan 18 14:07:44 2019
China reached the barrier at: Fri Jan 18 14:07:44 2019
Japan reached the barrier at: Fri Jan 18 14:07:46 2019
USA reached the barrier at: Fri Jan 18 14:07:46 2019
All Reached Barrier Point!
このように、各スレッドはランダムな時間だけ処理を続けた後バリアに到達して待機し、最後の1つ(USA)が到達した時点で全員が同時に解放されていることがわかります。マルチスレッド処理において、複数スレッドの足並みを揃えたい場面で、バリアは非常に有効な同期ツールです。
-
Pythonのファイルオブジェクトとは?open関数によるファイル操作の基本を徹底解説
Pythonでは、ファイルを読み書きする際に特別なライブラリをインポートする必要はありません。ファイル操作は言語にネイティブに組み込まれているためです。 まず最初に行うのは、組み込み関数 open() を使ってファイルオブジェクトを取得することです。open() 関数はファイルを開き、ファイルオブジェクトを返します。このファイルオブジェクトには、開いたファイルから情報を取得したり、内容を操作したりするためのメソッドや属性が含まれています。 ファイルとは何か? ファイル操作を行う前に、「ファイルとは何か」を理解しておきましょう。ファイルとは、関連する情報を保存するためにディスク上に確保された「名
-
Pythonの関数はオブジェクトなのか?属性を持たせる方法を解説
Pythonの関数はオブジェクトである結論から言うと、Pythonの関数は完全なオブジェクトです。def文やlambda式を使うと、Pythonは自動的に関数オブジェクトを生成します。通常のオブジェクトと同様に、関数にも属性(アトリビュート)を持たせたり、後から参照したりすることができます。さらに、関数の中にはデータ変数だけでなく、別の関数を定義することも可能です。サンプルコード以下の例では、def文で作成した関数に「score」という属性を代入し、その値を取得しています。また、lambda式で生成したオブジェクトの型も確認しています。def foo(): pass foo.score = 2