一.Lock and RLock
需要zookeeper的python 客户端kazoo
# -*- coding: utf-8 -*-
import os
import uuid
from kazoo.client import KazooClient
from kazoo.recipe.lock import Lock
class ZkLock(object):
def __init__(self,lockname,zkhosts,basepath='/locks',logger=None,timeout=5):
self._zk_hosts = zkhosts
#
self._client = KazooClient(hosts=self._zk_hosts,logger=logger,timeout=timeout)
self._zk_path = os.path.join(basepath,lockname)
self._lock_handle = Lock(self._client,self._zk_path)
def start(self):
self._client.start()
def stop(self):
self._client.stop()
def acquire(self, blocking=True, timeout=None):
self.start()
return self._lock_handle.acquire(blocking=blocking, timeout=timeout)
def release(self):
return self._lock_handle.release()
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.release()
class ZkRLock(ZkLock):
def __init__(self, lockname, basepath='/locks', zkhosts=None, timeout=5):
super(ZkRLock,self).__init__(lockname=lockname, basepath=basepath, zkhosts=zkhosts, timeout=timeout)
# self._is_acquired = False
self._token = uuid.uuid4().hex
self.__owner = None
self.__count = 0
def acquire(self,blocking=True, timeout=None):
if self.__owner == self._token:
self._is_acquired = True
self.__count += 1
return True
self.start()
rc = self._lock_handle.acquire(blocking=blocking,timeout=timeout)
if rc:
self.__owner = self._token
self.__count = 1
return rc
def release(self):
# if self.__owner != self._token:
# raise RuntimeError("cannot release un-acquired lock")
self.__count -= 1
if not self.__count:
self.__owner = None
return self._lock_handle.release()
来源:oschina
链接:https://my.oschina.net/u/2882233/blog/738737