1

スレッドセーフを確保し、競合状態を回避するために、PythonクラスでJavaメソッド同期のような監視スレッド同期を使用する方法はありますか?

クラスまたはオブジェクトで1つのメソッド呼び出しのみを許可する同期メカニズムのようなモニターが必要です

4

2 に答える 2

6

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(ただし、デコレータを使用して構築できると思います)

于 2012-07-04T19:38:53.247 に答える
1

簡単なプロトタイプを作成しました。詳細については、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>
于 2020-12-11T02:24:14.023 に答える