简体   繁体   English

在Mac OS X上与EnterCriticalSection最佳等效?

[英]Best equivalent for EnterCriticalSection on Mac OS X?

What's the best equivalent? 最好的等效是什么? I didn't find any reasonable solution for such a simple function. 对于这种简单功能,我没有找到任何合理的解决方案。 Choices I'm aware of: 我知道的选择:

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

2) OSSpinLockLock - unusable, because apparently not recursive. 2)OSSpinLockLock-无法使用,因为显然不是递归的。 If it would be recursive, it would be the correct equivalent. 如果它是递归的,那将是正确的等效项。

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

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): 假设您具有正确工作的非递归锁,那么很容易获得有效的递归锁(不了解Mac API,所以这是伪代码):

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
};

It's simple to reason: 原因很简单:

  • if tid == owner it's guaranteed that we have already acquired the lock. 如果tid == owner则可以确保我们已经获得了锁。
  • 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. 如果tid != owner要么有人持有该锁,要么是免费的,在两种情况下,我们都尝试获取该锁并进行阻塞,直到获得它为止。 After we acquire the lock we set the owner to tid. 获取锁后,将所有者设置为tid。 So there's some time where we have acquired the lock but owner is still illegal. 因此,有些时候我们已经获得了锁,但是owner仍然是非法的。 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. 但是没问题,因为非法的tid也不会等于任何真实线程的tid,因此它们也将进入else分支并必须等待获取它。

Notice the std::atomic part - we do need ordering guarantees for the owner field to make this legal. 注意std::atomic部分-我们确实需要对owner字段进行订购保证才能使此合法。 If you don't have c++11 use some compiler intrinsic for that. 如果您没有c ++ 11,请使用一些内在的编译器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM