代码之家  ›  专栏  ›  技术社区  ›  Dominic Rodger

确保只能从锁定状态调用某些专用函数

  •  1
  • Dominic Rodger  · 技术社区  · 14 年前

    说我有课 A :

    class A {
    public:
       A();
    
       void fetch_data() { return 1; }
       void write_x_data() {
         // lock this instance of A
         private_function1_which_assumes_locked();
         private_function2_which_assumes_locked();
         // unlock this instance of A
       }
       void write_y_data() {
         // lock this instance of A
         private_function1_which_assumes_locked();
         // unlock this instance of A
       }
    private:
       void private_function1_which_assumes_locked();
       void private_function2_which_assumes_locked();
    };
    

    private_function*_which_assumed_locked() A. 锁上了。

    实现这一目标的最佳方式是什么?我有5个左右需要锁定的公共函数。这些函数从不互相调用,所以我不担心这些函数会死锁。这5个公共函数组合起来调用大约15个不同的私有函数,这些函数需要假定对象处于锁定状态。显然,我不能锁定私有函数,因为我会遇到死锁。

    假设互斥体和 Scopeguards .

    在Python中,我可能会做一些事情 喜欢 这个 decorators

    class locked_method(object):
        def __init__(self, f):
            self.f = f
    
        def __call__(self):
            # Do whatever is needed to lock
            self.f()
            # Do whatever is needed to unlock
    
    class checklocked(object):
        def __init__(self, f):
            self.f = f
    
        def __call__(self):
            # check locked, if not, don't call self.f(),
            # and yell at me loudly for screwing up.
            self.f()
    
    @locked_method
    def func1():
        __function_which_assumes_locked()
    
    @checklocked
    def __function_which_assumes_locked():
        pass
    

    NB:我没有用Python做很多事情,所以如果我的Python是错误的/愚蠢的,请自由地评论,但是这个问题的观点更是C++中实现这类事情的最好方式,所以希望Python提供的内容足以让你知道我想做什么。

    6 回复  |  直到 14 年前
        1
  •  4
  •   Mike Seymour    14 年前

    您可以使用一个locker类,并要求存在一个以调用私有函数:

    class A
    {
    public:
        void write()
        {
            Lock l(this);
            write(l);
        }
    
    private:
        void lock();
        void unlock();
        void write(const Lock &);
    
        class Lock
        {
        public:
            explicit Lock(A *a) : parent(a) {parent->lock();}
            ~Lock() {parent->unlock();}
        private:
            A *parent;
        };
    };
    
        2
  •  2
  •   Éric Malenfant    14 年前

    这让我想起了一个 Dr. Dobb's article by Andrei Alexandrescu .

    class Foo
    {
    public:
        // Not the "volatile"
        int External() volatile
        {
            return this->Internal();
        }
    
    private:
    
        // Not volatile
        int Internal();
    };
    

    因为 this 无法从中转换 Foo volatile* Foo*

    class Foo
    {
    public:
        int External() volatile
        {
            Lock self(this);
            return self->Internal();
        }
    
    private:
    
        class Lock{
        public:
            explicit Lock(volatile Foo* Self)
                : m_Mutex.Aquire(),
                  m_Self(const_cast<Foo*>(Self))
            {}
    
            ~Lock()
            {
                m_Mutex.Release();
            }
    
            Foo* operator->(){
                return m_Self;
            }
    
        private:
            SomeMutexType m_Mutex;
            Foo* m_Self;
        };
    
    
        int Internal();
    };
    
        3
  •  0
  •   Dror Helper    14 年前

    您可以使用“#Define”创建类似的效果:

    #define CheckIfLocked(func, criticalSection) \
        // here you can enter the critical section
        func \
        // exit critical section
    
        4
  •  0
  •   Danra Bathsheba    14 年前

    你可以使用C++之一 locking mechanisms .

    使用中的一个“Try”-ing函数作为每个私有函数的第一步-这些函数只是检查锁是否已锁定。如果未锁定,则抛出异常。

    -时间。。。这在Haskell中可能是可能的:)

        5
  •  0
  •   Houlalala    14 年前

    查看RAII以锁定/解锁对象(或使用类似 boost::mutex::scoped_lock ).

        6
  •  0
  •   user3458 user3458    14 年前

    函数的作用是:锁定互斥锁,并将线程id放入成员变量中。 unlock()将成员变量设置为0并解锁互斥锁

    在您的私有函数中,检查线程id是否是您自己线程的id,如果不是,请大声抱怨。