ReadWriteLock

Codacy Badge License MIT CocoaPods Compatible Carthage Compatible Platform Code Coverage

Swift Package Xcode Project Cocoapods Carthage

ReadWriteLock 是一个轻量级框架,它为 iOS、macOS、tvOS 和 watchOS 提供了一种安全且易于实现的读写锁。

安装

ReadWriteLock 可通过 CocoaPodsCarthageSwift Package Manager 安装。

要通过 CocoaPods 安装,只需将以下行添加到您的 Podfile 中

pod 'ReadWriteLock'

要通过 Carthage 安装,只需将以下行添加到您的 Cartfile 中

github "SomeRandomiOSDev/ReadWriteLock"

要通过 Swift Package Manager 安装,请将以下行添加到您的 Package.swift 文件的 dependencies

.package(url: "https://github.com/SomeRandomiOSDev/ReadWriteLock.git", from: "1.0.0")

使用

首先在您的 Swift 文件顶部导入 ReadWriteLock

import ReadWriteLock

导入后,只需实例化一个 ReadWriteLock 实例并开始获取锁

let lock = ReadWriteLock()
var protectedResource = ...

DispatchQueue.global(qos: .background).async {
    ...

    lock.acquireWriteLock {
        protectedResource = ...
    }
}

...

DispatchQueue.global(qos: .background).async {
    ...
    
    lock.acquireReadLock {
        process(protectedResource)
    }
}

或者您可以有条件地尝试获取锁。如果锁已被声明,以这种方式获取锁将不会阻塞

...

lock.attemptAcquireReadLock { isLockAcquired in
    if isLockAcquired {
        process(protectedResource)
    } else {
        // `lock` is currently locked for writing. 
    }
}

获取锁使用 Swift 闭包来限定读/写锁的生命周期。 这可以防止在 ReadWriteLock 对象被释放时出现悬而未决的锁,并有助于防止死锁。 请注意,如果您尝试从已获取的读或写锁的范围内获取写锁,或者从已获取的写锁的范围内获取读锁,则线程将死锁

// All of these code blocks will deadlock

lock.acquireWriteLock {
    ...
    
    lock.acquireWriteLock {
        // deadlock
    }
}

lock.acquireReadLock {
    ...

    lock.acquireWriteLock {
        // deadlock
    }
}

lock.attemptAcquireWriteLock { isLockAcquired in
    ...

    if isLockAcquired {
        lock.acquireWriteLock {
            // deadlock
        }
    }
}

...

读/写锁相对于传统锁的优势在于,您可以拥有(实际上)无限数量的读锁,甚至是嵌套的读锁,而不会导致死锁

lock.acquireReadLock {
    ...
    
    lock.acquireReadLock {
        // won't deadlock
    }
    
    lock.attemptAcquireReadLock { isLockAcquired in 
        // isLockAcquired is `true`
    }
}

读/写锁非常适合同步对属性的访问

struct SynchronizedValue<T> {
    private var lock = ReadWriteLock()
    private var _value: T
    
    var value: T {
        get {
            return lock.acquireReadLock { _value }
        }
        set {
            lock.acquireWriteLock { _value = newValue }
        }
    }
}

贡献

如果您需要某个特定功能或遇到错误,请打开一个 issue。 如果您自己扩展了 ReadWriteLock 的功能,或者您想自己修复一个 bug,请提交一个 pull request。

作者

Joe Newton, somerandomiosdev@gmail.com

许可证

ReadWriteLock 基于 MIT 许可证发布。 有关更多信息,请参阅 LICENSE 文件。