关于iOS读写锁,三种实现方案对比,第三种实现方案会造成写饥饿
一.系统读写锁
class LockTest {
private let queue = DispatchQueue(label: "com.concurrent.queue",attributes: .concurrent)
private var rwlock:pthread_rwlock_t
init() {
rwlock = pthread_rwlock_t()
pthread_rwlock_init(&rwlock, nil)
}
public func testPThreadRWLock() {
readThread(num: 1)
readThread(num: 2)
writeThread(num: 1)
readThread(num: 3)
readThread(num: 4)
writeThread(num: 2)
readThread(num: 5)
readThread(num: 6)
writeThread(num: 3)
readThread(num: 7)
readThread(num: 8)
readThread(num: 9)
writeThread(num: 4)
readThread(num: 10)
readThread(num: 11)
readThread(num: 12)
writeThread(num: 5)
readThread(num: 13)
}
private func readThread(num:Int) {
queue.async {
pthread_rwlock_rdlock(&self.rwlock)
Thread.sleep(forTimeInterval: 1)
print("read\(num)")
pthread_rwlock_unlock(&self.rwlock)
}
}
private func writeThread(num:Int) {
queue.async {
pthread_rwlock_wrlock(&self.rwlock)
Thread.sleep(forTimeInterval: 1)
print("write\(num)")
pthread_rwlock_unlock(&self.rwlock)
}
}
}
let lockTest:LockTest = LockTest()
lockTest.testPThreadRWLock()
输出结果
read1
read2
write1
read3
read4
write2
read5
read6
write3
read8
read7
read9
write4
read11
read10
read12
write5
read13
二.GCD barrierAsync
class LockTest {
private let queue = DispatchQueue(label: "com.concurrent.queue",attributes: .concurrent)
public func testBarrierRWLock() {
readThread(num: 1)
readThread(num: 2)
writeThread(num: 1)
readThread(num: 3)
readThread(num: 4)
writeThread(num: 2)
readThread(num: 5)
readThread(num: 6)
writeThread(num: 3)
readThread(num: 7)
readThread(num: 8)
}
private func readThread(num:Int) {
queue.async {
Thread.sleep(forTimeInterval: 0.2)
print("read\(num)")
}
}
private func writeThread(num:Int) {
queue.async(flags: .barrier) {
Thread.sleep(forTimeInterval: 0.2)
print("write\(num)")
}
}
}
let lockTest:LockTest = LockTest()
lockTest.testBarrierRWLock()
输出
read1
read2
write1
read3
read4
write2
read5
read6
write3
read8
read7
三.自定义实现读写锁
class CustomRWLock {
//读数量
private var readCount:Int = 0
//读锁
private var rlock:NSLock = NSLock()
//写锁
private var wlock:NSLock = NSLock()
public func rdLock(){
rlock.lock()
if readCount == 0 {
wlock.lock()
}
readCount = readCount + 1
rlock.unlock()
}
public func wrLock(){
wlock.lock()
}
public func rdUnlock(){
rlock.lock()
readCount = readCount - 1
if readCount == 0 {
wlock.unlock()
}
rlock.unlock()
}
public func wrUnlock(){
wlock.unlock()
}
}
class LockTest {
private let queue = DispatchQueue(label: "com.concurrent.queue",attributes: .concurrent)
private var custRwLock:CustomRWLock = CustomRWLock()
public func testCustomRWLock(){
readThread(num: 1)
readThread(num: 2)
writeThread(num: 1)
readThread(num: 3)
readThread(num: 4)
writeThread(num: 2)
readThread(num: 5)
readThread(num: 6)
writeThread(num: 3)
readThread(num: 7)
readThread(num: 8)
writeThread(num: 4)
readThread(num: 9)
readThread(num: 10)
writeThread(num: 5)
readThread(num: 11)
readThread(num: 12)
}
private func readThread(num:Int) {
queue.async {
self.custRwLock.rdLock()
Thread.sleep(forTimeInterval: 1)
print("read\(num)")
self.custRwLock.rdUnlock()
}
}
private func writeThread(num:Int) {
queue.async {
self.custRwLock.wrLock()
Thread.sleep(forTimeInterval: 1)
print("write\(num)")
self.custRwLock.wrUnlock()
}
}
}
let lockTest:LockTest = LockTest()
lockTest.testCustomRWLock()
输出:
read1
read3
read10
read7
read6
read8
read9
read11
read2
read4
read5
read12
write1
write2
write3
write4
write5
推荐文档:
- zhuanlan.zhihu.com/p/91408261 Java 读写锁ReentrantReadWriteLock,注意ReentrantReadWriteLock内部实现了公平与非公平两种特性
- www.cnblogs.com/fortunely/p… C++读写锁,写优先,读可能饥饿问题