definition
Mutex lock:
NSLock mutex only allows one thread to perform one task at the same time. That is, the same process acquires and the same thread releases.
Recursive lock:
The lock defined by the NSRecursiveLock class can be locked multiple times on the same thread without causing deadlock. A recursive lock keeps track of how many times it has been locked. Each successful lock must be balanced by a call to the unlock operation. Only when all locking and unlocking operations are balanced, the lock is actually released for other threads to acquire.
the difference:
Mutex locks can be divided into two types: non-recursive locks and recursive locks. The main difference is that the same thread can repeatedly acquire recursive locks without deadlock; if the same thread repeatedly acquires non-recursive locks, deadlock will occur.
Code:
If the following code uses a mutex lock, it will deadlock because lock is called multiple times on the same thread without calling unlock an equal number of times.
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()
The example described above will cause a deadlock. Lock is called within a recursive function, and lock is called multiple times on the same thread without calling unlock the same number of times.
So will the following code deadlock?
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()
}
}
}
The answer will also cause a deadlock. Although it is not called within a recursive function, lock is called multiple times on the same thread without calling unlock the same number of times. Therefore, a deadlock will still occur.
reference
- https://juejin.cn/post/7007983045345034247
- https://cloud.tencent.com/developer/article/1037807