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

标签 multithreading macos performance critical-section

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

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

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

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

最佳答案

假设您具有正确工作的非递归锁,那么很容易获得有效的递归锁(不了解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
};

原因很简单:
  • 如果是tid == owner,则可以确保我们已经获取了锁。
  • 如果tid != owner要么有人持有该锁,要么它是免费的,在这两种情况下,我们都尝试获取该锁并进行阻塞,直到获得它为止。获取锁后,将所有者设置为tid。因此,有些时候我们已经获得了锁,但是owner仍然是非法的。但是没有问题,因为非法的tid也不会等于任何真实线程的tid,因此它们也将进入else分支,必须等待获取。

  • 注意std::atomic部分-我们确实需要owner字段的顺序保证才能使其合法。如果您没有c++ 11,则可以使用一些内在的编译器。

    关于multithreading - 在Mac OS X上与EnterCriticalSection最佳等效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24533965/

    相关文章:

    C# 从循环中启动线程抛出 IndexOutOfBoundsException

    java - 如何在不使用 ExecutorService 的情况下获得 Future<MyObject>?

    java - 在 Mac OSX 10.7.5 上的 Netbeans 中编译 Java 1.5 Web 应用程序

    java - 对于 boolean 值,(p ^ q) 和 (p != q) 之间是否存在有用的区别?

    javascript - Redux 性能每秒都会对存储进行大量更改

    java - 使用阻塞方法为多个客户端提供服务时的线程池

    Python : how to stop a thread that's waiting for a . recv()

    macos - 下载 Rosetta 的软件包副本,以便在没有互联网的情况下手动传输到另一台 Mac

    ios - Testflight 在 Mac OS X 桌面应用程序中找不到 SDK?

    c++ - 检查零更有效吗?