スレッドセーフを確保し、競合状態を回避するために、PythonクラスでJavaメソッド同期のような監視スレッド同期を使用する方法はありますか?
クラスまたはオブジェクトで1つのメソッド呼び出しのみを許可する同期メカニズムのようなモニターが必要です
スレッドセーフを確保し、競合状態を回避するために、PythonクラスでJavaメソッド同期のような監視スレッド同期を使用する方法はありますか?
クラスまたはオブジェクトで1つのメソッド呼び出しのみを許可する同期メカニズムのようなモニターが必要です
Pythonスレッドインターフェイスを確認することをお勧めします。単純な相互排除機能の場合、Lock
オブジェクトを使用できます。with
次のようなステートメントを使用して、これを簡単に行うことができます。
...
lock = Lock()
...
with (lock):
# This code will only be executed by one single thread at a time
# the lock is released when the thread exits the 'with' block
...
Pythonのさまざまなスレッド同期メカニズムの概要については、こちらも参照してください。
Java用のPython言語構造はありませんsynchronized
(ただし、デコレータを使用して構築できると思います)
簡単なプロトタイプを作成しました。詳細については、GitHubリポジトリへのリンクをご覧ください:https ://github.com/ma-rahal/monitor-sync-python
デコレータの代わりに継承を使用しましたが、後でそのオプションを含める可能性があります。
「Monitor」スーパークラスは次のようになります。
import threading
class Monitor(object):
def __init__(self, lock = threading.Lock()):
''' initializes the _lock, threading.Lock() is used by default '''
self._lock = lock
def Condition(self):
''' returns a condition bound to this monitor's lock'''
return threading.Condition(self._lock)
init_lock = __init__
これで、独自のモニターを定義するために必要なのは、このクラスから継承することだけです。
class My_Monitor_Class(Monitor):
def __init__(self):
self.init_lock() # just don't forget this line, creates the monitor's _lock
cond1 = self.Condition()
cond2 = self.Condition()
# you can see i defined some 'Condition' objects as well, very simple syntax
# these conditions are bound to the lock of the monitor
代わりに独自のロックを渡すこともできます
class My_Monitor_Class(Monitor):
def __init__(self, lock):
self.init_lock(lock)
threading.Condition()のドキュメントを確認してください
また、次のように、すべての「public」メソッドをモニターのロックで保護する必要があります。
class My_Monitor_Class(Monitor):
def method(self):
with self._lock:
# your code here
'private'メソッド(モニター内で呼び出される)を使用する場合は、 (またはスレッドがスタックする)でそれらを保護しないか、モニターの代わりにRLockを使用することができます。_lock
モニターが「入口」プロトコルと「出口」プロトコルで構成される場合もあります
monitor.enter_protocol()
<critical section>
monitor.exit_protocol()
この場合、Pythonのクールなwith
ステートメント:3を利用して、とメソッドを次のよう
に定義することができます。__enter__
__exit__
class monitor(Monitor):
def __enter__(self):
with self._lock:
# enter_protocol code here
def __exit__(self, type, value, traceback):
with self._lock:
# exit_protocol code here
今、あなたがする必要があるのは、ステートメントを使用してモニターを呼び出すことです:
with monitor:
<critical section>