在python中监视线程同步

时间:2012-07-04 19:20:05

标签: python synchronization

有没有办法在python类中使用监听线程同步如java方法同步,以确保线程安全并避免竞争条件?

我想要一个像同步机制这样的监视器,它只允许在我的类或对象中调用一个方法

2 个答案:

答案 0 :(得分:5)

您可能需要查看python threading interface。对于简单的互斥功能,您可以使用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
  ...

另请参阅here以获取python中不同线程同步机制的概述。

Java synchronized没有python语言构造(但我猜它可以使用装饰器构建)

答案 1 :(得分:1)

我为此构建了一个简单的原型,这是指向GitHub存储库的所有详细信息的链接:https://github.com/m-a-rahal/monitor-sync-python

我使用继承而不是装饰器,但也许以后我会包括该选项
这是“监视器”超类的样子:

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()文档

此外,您还需要使用监视器的锁来保护所有“公共”方法,例如:

class My_Monitor_Class(Monitor):
    def method(self):
        with self._lock:
            # your code here

如果要使用“私有”方法(在监视器内部调用),则可以_lock保护它们(否则线程将被卡住),或者使用RLock代替显示器

额外提示

有时监视器由“进入”和“退出”协议组成

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 statement调用监视器:

with monitor: 
    <critical section>