iPhone development--recursive lock

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

Guess you like

Origin blog.csdn.net/zcl369369/article/details/129027954