2016-04-21 2 views
1

Я хочу, чтобы блокировка LockQueue2 для завершения процесса и при разблокировке LockQueue2 показать "number is:" number in dispatch_after.Заблокировать и разблокировать dispatch_queue_t в async task

мне нужен этот вывод:

число, установленное значение 1
номер 1
число, установленное значение 2
номер 2
число, установленное значение 3
число является 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) 
+0

Если вы хотите, чтобы какой-нибудь случайный поток ожидал другого, вы, вероятно, используете семафоры, а не блокировку. Итак, создайте семафор, попросите второй процесс ждать сигнала, а затем сначала обработайте сигнал, который семафор. или использовать последовательную очередь. – Rob

+0

Спасибо, дорогой @Rob, не могли бы вы привести мне пример? – solan

ответ

0

Если yo u're дело с простыми синхронными задачами, как вы, вы можете просто использовать серийные очереди:

let serialQueue = dispatch_queue_create("com.domain.app.serialqueue", nil) 

func simpleSerialQueue(num: Int) { 
    var number = 0 

    dispatch_async(serialQueue){ 
     sleep(2) 
     number = num 
     print("number set value: ", number) 
    } 

    dispatch_async(serialQueue) { 
     print("number is:", number)//*** show number set in last dispatch *** 
    }   
} 

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

Или, если у вас асинхронная задача, для которой вы хотели дождаться его завершение, вы можете использовать семафор:

let serialQueue = dispatch_queue_create("com.domain.app.serialqueue", nil) 

func semaphoreExample(num: Int) { 
    var number = 0 

    let semaphore = dispatch_semaphore_create(0) 

    // this will fire in 2 seconds 

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(NSEC_PER_SEC * 2)), serialQueue) { 
     number = num 
     print("number set value: ", number) 
     dispatch_semaphore_signal(semaphore); 
    } 

    // this will start immediately, but will wait until the above semaphore is signaled 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { 
     print("going to wait for semaphore") 
     dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER) 
     print("number is:", number) 
    } 
} 

semaphoreExample(1) 

Честно говоря, семафоры, вероятно, будет мое решение последней инстанции, как в целом, другие подходы, справиться с этим более элегантно. Например, я могу использовать асинхронный подкласс класса NSOperation при работе с асинхронными процессами: он требует немного больше настройки вверх, но очень эффективно обрабатывает асинхронные задачи. См. WWDC 2015 Advanced NSOperations для надежного примера.

+0

Это очень полный ответ, раздел 2 решил мою проблему, очень спасибо. – solan

Смежные вопросы