iPhone开发--递归锁

定义
互斥锁:

NSLock互斥量只允许一个线程同时执行一个任务。也就是同一个程获取,同一个线程释放。

递归锁:

NSRecursiveLock类定义的锁可以在同一线程多次lock,而不会造成死锁。递归锁会跟踪它被多少次lock。每次成功的lock都必须平衡调用unlock操作。只有所有的锁住和解锁操作都平衡的时候,锁才真正被释放给其他线程获得。

区别:

互斥锁可以分为非递归锁/递归锁两种,主要区别在于:同一个线程可以重复获取递归锁,不会死锁; 同一个线程重复获取非递归锁,则会产生死锁。

代码:

如下代码,如果使用互斥锁,则会死锁,因为在同一个线程多次调用了lock而未调用同等次数的unlock

let lock = NSLock()
let queue = DispatchQueue.init(label: "RyukieQ", qos: .default, attributes: .concurrent, autoreleaseFrequency: .workItem, target: nil)
    
func testLog1(times: Int) {
    
    
        lock.lock() // 不断递归加锁
        print("\(times) 线程: \(Thread.current)")
        if times > 0 {
    
    
            testLog1(times: times - 1)
        }
        lock.unlock()
    }

func demo() {
    
    
	for _ in 0..<10 {
    
    
		queue.async {
    
    
//                self.lock.lock() // 不断递归加锁
		self.testLog1(times: 10)
//                self.lock.unlock()
        }
    }
}
demo()

上描的例子会造成死锁,在递归的函数内调用了lock,在同一个线程多次调用了lock而未调用同等次数的unlock。
那么如下代码会不会死锁呢?

    func testLog1(times: Int) {
    
    
        lock1.lock() // 不断递归加锁
        print("\(times) 线程: \(Thread.current)")
        testLog2(times: times)
        lock1.unlock()
    }

	func testLog2(times: Int) {
    
    
        lock1.lock() // 不断递归加锁
        print("2 \(times) 线程: \(Thread.current)")
        lock1.unlock()
    }

	func demo() {
    
    
        for _ in 0..<10 {
    
    
            queue.async {
    
    
//                self.lock1.lock() // 不断递归加锁
                self.testLog1(times: 10)
//                self.lock1.unlock()
                
            }
        }
    }

答案也会造成死锁,虽然不是在递归函数内调用,但是还是在同一个线程多次调用了lock而未调用同等次数的unlock。故还是会造成死锁。

参考

  • https://juejin.cn/post/7007983045345034247
  • https://cloud.tencent.com/developer/article/1037807

猜你喜欢

转载自blog.csdn.net/zcl369369/article/details/129027954