在Mac OS X上与EnterCriticalSection最佳等效? [英] Best equivalent for EnterCriticalSection on Mac OS X?

查看:211
本文介绍了在Mac OS X上与EnterCriticalSection最佳等效?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最好的等效词是什么?对于这种简单功能,我没有找到任何合理的解决方案.我知道的选择:

What's the best equivalent? I didn't find any reasonable solution for such a simple function. Choices I'm aware of:

1)MPEnterCriticalRegion-不幸的是,这是极其无效的,可能是因为尽管它的名字叫它进入了内核模式,所以对于重复锁定它只花费了太多时间...

1) MPEnterCriticalRegion - this is unfortunately extremely ineffective, probably because despite it's name it enters kernel mode, so for repeating locks it just takes way too much time...

2)OSSpinLockLock-无法使用,因为它显然不是递归的.如果它是递归的,那将是正确的等效项.

2) OSSpinLockLock - unusable, because apparently not recursive. If it would be recursive, it would be the correct equivalent.

3)pthread_mutex_lock-没尝试,但是我期望不高,因为它可能只是使用关键区域或其他系统资源来模拟.

3) pthread_mutex_lock - didn't try, but I don't expect much, because it will probably be just emulated using the critical region or another system resource.

推荐答案

假设您具有正确工作的非递归锁,那么获得有效的递归锁相当容易(不了解Mac API,所以这是伪代码) :

Assuming you have a correctly working non-recursive lock, it's rather easy to get an efficient recursive lock (no idea about Mac APIs, so this is pseudo code):

class RecursiveLock {
public:
    void acquire() {
        auto tid = get_thread_id();
        if (owner == tid) { 
            lockCnt++;
        } else {
            AcquireLock(lock);
            owner = tid;
            lockCnt = 1;
        }
    }

    void release() {
        assert(owner == get_thread_id());
        lockCnt--;
        if (lockCnt == 0) {
            owner = 0;  // some illegal value for thread id
            ReleaseLock(lock);
        }
    }

private:
    int lockCnt;
    std::atomic<void*> owner;  
    void *lock;   // use whatever lock you like here
};

原因很简单:

  • 如果tid == owner,则可以确保我们已经获取了锁.
  • 如果tid != owner有人持有锁或锁是免费的,在两种情况下,我们都尝试获取锁并阻塞直到获得.获取锁后,将所有者设置为tid.因此,有些时候我们已经获得了锁,但是owner仍然是非法的.但是没问题,因为非法的tid也不会等于任何真实线程的tid,因此它们也将进入else分支,并且必须等待获取.
  • if tid == owner it's guaranteed that we have already acquired the lock.
  • if tid != owner either someone else holds the lock or it's free, in both cases we try to acquire the lock and block until we get it. After we acquire the lock we set the owner to tid. So there's some time where we have acquired the lock but owner is still illegal. But no problem since the illegal tid won't compare equal to any real thread's tid either, so they'll go into the else branch as well and have to wait to get it.

请注意std::atomic部分-我们要做需要对owner字段进行排序保证,以使其合法.如果您没有c ++ 11,请为此使用一些内在的编译器.

Notice the std::atomic part - we do need ordering guarantees for the owner field to make this legal. If you don't have c++11 use some compiler intrinsic for that.

这篇关于在Mac OS X上与EnterCriticalSection最佳等效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆