针对多进程或者多线程访问共享数据时,经常需要在业务层控制锁,增加脑力负荷,这里设计一种通用的方式,锁操作直接封装在数据结构中。 直接贴代码

#!/usr/bin/env python
# encoding: utf-8

from multiprocessing import Lock, RLock


def make_property(name):
    try:
        return prop_cache[name]
    except KeyError:
        d = {}
        exec(template % ((name,) * 7), d)
        prop_cache[name] = d[name]
        return d[name]


template = '''
def get%s(self):
    self.acquire()
    try:
        return self._obj.%s
    finally:
        self.release()
def set%s(self, value):
    self.acquire()
    try:
        self._obj.%s = value
    finally:
        self.release()
%s = property(get%s, set%s)
'''

prop_cache = {}


class SynchronizedBase(object):

    def __init__(self, obj, lock=None):
        self._obj = obj
        if lock:
            self._lock = lock
        else:
            self._lock = RLock()

        self.acquire = self._lock.acquire
        self.release = self._lock.release

    def __enter__(self):
        return self._lock.__enter__()

    def __exit__(self, *args):
        return self._lock.__exit__(*args)

    def get_obj(self):
        return self._obj

    def get_lock(self):
        return self._lock

    def __repr__(self):
        return '<%s wrapper for %s>' % (type(self).__name__, self._obj)


class Synchronized(SynchronizedBase):
    value = make_property('value')


class Obj(object):
    def __init__(self, value):
        self.value = value


def SafeObj(obj, lock=None):
    return Synchronized(obj, lock)


if __name__ == '__main__':
    a = SafeObj(Obj(3))
    b = SafeObj(Obj(4), Lock())
    print(a.value)
    print(b.value)

SafeObjObj进行包装,返回一个含有同步原语的对象。由于足够抽象,对它的访问行为和对Obj一致。 代码还可以再进行扩展,比如Synchronized怎样怎样访问Objmethod等。


未央
14 声望5 粉丝

计划|执行|精进