锁-读写锁-Swift
实现一 pthread_mutex_t:
ReadWriteLock/Sources/ReadWriteLock at main · SomeRandomiOSDev/ReadWriteLock · GitHub
https://swiftpackageindex.com/reers/reerkit/1.0.39/documentation/reerkit/readwritelock/
//
// Copyright © 2022 reers.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#if canImport(Darwin)
import Darwin
/// ReerKit: Represents a reader-writer lock. Note that this implementation is not recursive.
public final class ReadWriteLock {
private var readMutex = pthread_mutex_t()
private var writeMutex = pthread_mutex_t()
private var readCount: UInt = 0
public init() {
pthread_mutex_init(&readMutex, nil)
pthread_mutex_init(&writeMutex, nil)
}
deinit {
pthread_mutex_destroy(&readMutex)
pthread_mutex_destroy(&writeMutex)
}
public func readLock() {
pthread_mutex_lock(&readMutex)
defer { pthread_mutex_unlock(&readMutex) }
if readCount == 0 {
pthread_mutex_lock(&writeMutex)
}
readCount += 1
}
/// ReerKit: Returns true if the lock was succesfully locked and false if the lock was already locked.
@discardableResult
public func tryReadLock() -> Bool {
pthread_mutex_lock(&readMutex)
defer { pthread_mutex_unlock(&readMutex) }
let success = (readCount == 0)
? pthread_mutex_trylock(&writeMutex) == 0
: true
if success {
readCount += 1
}
return success
}
public func readUnlock() {
pthread_mutex_lock(&readMutex)
defer { pthread_mutex_unlock(&readMutex) }
if readCount > 0 {
readCount -= 1
if readCount == 0 {
pthread_mutex_unlock(&writeMutex)
}
}
}
public func writeLock() {
pthread_mutex_lock(&writeMutex)
}
/// ReerKit: Returns true if the lock was succesfully locked and false if the lock was already locked.
@discardableResult
public func tryWriteLock() -> Bool {
return pthread_mutex_trylock(&writeMutex) == 0
}
public func writeUnlock() {
pthread_mutex_unlock(&writeMutex)
}
public func readAround<Result>(_ execute: () throws -> Result) rethrows -> Result {
readLock()
defer { readUnlock() }
return try execute()
}
public func writeAround<Result>(_ execute: () throws -> Result) rethrows -> Result {
writeLock()
defer { writeUnlock() }
return try execute()
}
}
#endif
实现二 NSLock:
class ReadWriteLockTT {
private let readLock = NSLock()
private let writeLock = NSLock()
private var readersCount = 0
func read() {
readLock.lock()
readersCount += 1
if readersCount == 1 {
writeLock.lock()
}
readLock.unlock()
}
func readUnlock() {
readLock.lock()
readersCount -= 1
if readersCount == 0 {
writeLock.unlock()
}
readLock.unlock()
}
func write() {
writeLock.lock()
}
func writeUnlock() {
writeLock.unlock()
}
func test() {
let rwLock = ReadWriteLockTT()
// // 模拟多个读操作线程
// DispatchQueue.concurrentPerform(iterations: 100) { _ in
// rwLock.read()
// // 这里执行读取共享资源的代码逻辑
// print("执行读取操作")
// rwLock.readUnlock()
// }
//
// // 模拟写操作线程
// DispatchQueue.global().async {
// rwLock.write()
// // 这里执行写入共享资源的代码逻辑
// print("执行写入操作")
// rwLock.writeUnlock()
// }
var value = 0
// 读线程
DispatchQueue.global().async {
for _ in 0..<20000 {
// rwLock.read { value in
// print("Read value: \(value)")
// }
rwLock.read()
// 这里执行读取共享资源的代码逻辑
print("执行读取操作==\(value)")
rwLock.readUnlock()
}
}
// 写线程
DispatchQueue.global().async {
for i in 1...5 {
sleep(1) // 模拟写操作的延迟
// rwLock.write(value: i)
rwLock.write()
// 这里执行写入共享资源的代码逻辑
value += 1
print("执行写入操作==\(value)")
rwLock.writeUnlock()
// print("Written value: \(i)")
}
}
DispatchQueue.global().asyncAfter(deadline: .now() + 200.0) {
print("打印完成")
}
sleep(200)
}
}
实现三 pthread_rwlock_t :
swift-design-patterns/Concurrency Design Patterns/ReadWriteLock/ReadWriteLock.md at main · eleev/swift-design-patterns · GitHub
import Foundation
class ReadWriteLock {
private var rwlock = pthread_rwlock_t()
init() {
pthread_rwlock_init(&rwlock, nil)
}
deinit {
pthread_rwlock_destroy(&rwlock)
}
func read<T>(_ closure: () -> T) -> T {
pthread_rwlock_rdlock(&rwlock)
defer { pthread_rwlock_unlock(&rwlock) }
return closure()
}
func write(_ closure: () -> Void) {
pthread_rwlock_wrlock(&rwlock)
defer { pthread_rwlock_unlock(&rwlock) }
closure()
}
}
let readWriteLock = ReadWriteLock()
// Reading data with a read lock
let data = readWriteLock.read { () -> Data in
// Read shared data here
return sharedData
}
// Writing data with a write lock
readWriteLock.write {
// Modify shared data here
sharedData = newData
}
实现四 NSRecursiveLock 递归锁:
TODO: