在异步任务中锁定和解锁 dispatch_queue_t

lock and unlock dispatch_queue_t in async task

我想要锁定 LockQueue2 以完成进程,当解锁 LockQueue2 时显示 "number is :" number in dispatch_after.

我需要这个输出:

number set value 1
number is 1
number set value 2
number is 2
number set value 3
number is 3

let LockQueue = dispatch_queue_create("LockQueue", nil)

func test(num :Int){
  var number = 0
  let LockQueue2 = dispatch_queue_create("LockQueue2", nil)

  dispatch_async(LockQueue){
    LockQueue2.lock()
    // any process or waiting
    sleep(2)
    dispatch_sync(LockQueue2) {
             number = num
             print("number set value ", number)
           LockQueue2.unlock()
    }
  } 
  dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0)){
     // any process or waiting
     sleep(3)
     dispatch_after(LockQueue2) {
         print("number is :", number)//*** show number set in last dispatch ***            
     } 
  }          
 }

test(1)
test(2)
test(3)

如果您正在处理简单的同步任务,就像您一样,您可以只使用串行队列:

let queue = DispatchQueue(label: "com.domain.app.serialqueue")
var number = 0

func simpleSerialQueue(_ num: Int) {
    queue.async { [self] in
        Thread.sleep(forTimeInterval: 2)
        number = num
        print("number set value: ", number)
    }

    queue.async { [self] in
        let value = number
        DispatchQueue.global(qos: .background).async {
            print("number is:", value) //*** show number set in last dispatch ***
        }
    }
}

simpleSerialQueue(1)
simpleSerialQueue(2)
simpleSerialQueue(3)

如您所见,我会让队列协调我的进程,排除使用信号量等,这些信号量很容易被误用并导致死锁。

如果这些任务中的过程本身是异步的,它可能需要其他模式(组合、自定义异步 Operation 子类等)。但是对于像这样简单的同步任务,串行调度队列就足够了。


请参阅此答案的 previous revision 以获得 Swift 2 版本。