2017-06-13 49 views
1

有人可以用简单的例子回答:GCD临界区/互斥

如何正确锁码部分与条件:如果这部分是由一些线程不持有其他线程锁定只是通过其他跳过这部分线程并继续前进。

+1

您可以使用一个信号量。对于“尝试锁定”操作,使用DISPATCH_TIME_NOW调用dispatch_semaphore_wait()作为timeout参数。如果它返回非零值,那么超时,意味着别的东西持有锁,你应该跳过你的操作。 –

+0

dispatch_semaphore_wait()增加信号量计数器+1谁会减少这个比? – ObranS

+1

'dispatch_semaphore_wait()'尝试**减少信号量计数器。 'dispatch_semaphore_wait()'类似于锁定锁; 'dispatch_semaphore_signal()'类似于解锁它。信号量将从1开始,表示它已解锁,并且一个客户端可以一次锁定它。 –

回答

0

好吧,这里是工作示例(归功于@KenThomases ...)

import Dispatch 

let semaphore = DispatchSemaphore(value: 1) 
let printQueue = DispatchQueue(label: "print queue") 
let group = DispatchGroup() 

func longRuningTask(i: Int) { 

    printQueue.async(group: group) { 
     print(i,"GREEN semaphore") 
    } 
    usleep(1000)    // cca 1 milisecond 
    printQueue.async(group: group) { 
     print(i,"job done") 
    } 
} 

func shortRuningTask(i: Int) { 
    group.enter() 
    guard semaphore.wait(timeout: .now() + 0.001) == .success else { // wait for cca 1 milisecond from now 
     printQueue.async(group: group) { 
      print(i,"RED semaphore, job not done") 
     } 
     group.leave() 
     return 
    } 
    longRuningTask(i: i) 
    semaphore.signal() 
    group.leave() 
} 

printQueue.async(group: group) { 
    print("running") 
} 

DispatchQueue.concurrentPerform(iterations: 10, execute: shortRuningTask) 
group.wait() 
print("all done") 

及其打印

running 
0 GREEN semaphore 
2 RED semaphore, job not done 
1 RED semaphore, job not done 
3 RED semaphore, job not done 
0 job done 
4 GREEN semaphore 
5 RED semaphore, job not done 
6 RED semaphore, job not done 
7 RED semaphore, job not done 
4 job done 
8 GREEN semaphore 
9 RED semaphore, job not done 
8 job done 
all done 
Program ended with exit code: 0