import Cocoa
/// 信号量对象
class DispatchSemaphore {
/// 创建一个信号量, 并设置初始值
/// - Parameters:
/// - value: 信号量的初始值。必须>=0,否则会返回NULL。
/// - Returns: 信号量对象
init(value: Int)
/// 发送信号量。该函数会对信号量的值进行+1操作。
/// - Returns:
/// - 当返回值=0时,表示当前不存在线程因为wait而阻塞。
/// - 当返回值>0时,表示其当前有(一个或多个)线程因为wait而阻塞,并且唤醒一个等待的线程(当线程有优先级时,唤醒优先级最高的线程;否则随机唤醒)。
func signal() -> Int
/// 等待信号量。该函数会对信号量的值进行-1操作。这个函数的作用是这样:
/// 如果信号量的值>0,该函数所处线程就继续执行下面的语句,并且将信号量的值-1;
/// 如果信号量的值=0,那么这个函数就阻塞当前线程等待timeout,
/// 如果等待期间信号量的值被signal函数+1了,且该函数(即dispatch_semaphore_wait)所处线程获得了信号量,那么就继续向下执行并将信号量-1。
/// 如果等待期间没有获取到信号量或者信号量的值一直为0,那么等到timeout时,其所处线程自动执行其后语句。
func wait()
/// 等待信号量。可以设置等待超时时间
/// - Parameters:
/// - timeout: DispatchTime为主板时间CPU时钟计时
/// - Returns:
/// - 当返回值=DispatchTimeoutResult.success时,表示在timeout之前,该函数所处的线程被成功唤醒。
/// - 当返回值=DispatchTimeoutResult.timedOut时,表示timeout发生。
func wait(timeout: DispatchTime) -> DispatchTimeoutResult
/// 等待信号量。可以设置等待超时时间
/// - Parameters:
/// - timeout: DispatchWallTime为实际时间即系统时间
/// - Returns:
/// - 当返回值=DispatchTimeoutResult.success时,表示在timeout之前,该函数所处的线程被成功唤醒。
/// - 当返回值=DispatchTimeoutResult.timedOut时,表示timeout发生。
func wait(wallTimeout: DispatchWallTime) -> DispatchTimeoutResult
}
/// 场景1: 将异步函数调整为同步, 因为wait的存在, 能够保证'step 5'一定能在'step 2'之后执行, 整个程序看上去像是顺序执行了。
/// 本场景中, 程序执行到wait时, 由于当前信号量为0, 会阻塞当前线程。
/// 此时global线程仍在并行执行, 它会等待2秒后, 执行signal让信号量加1。
/// 由于检测到有处于wait状态的线程(主线程), 于是将这个线程唤起, 这就造成了有两个线程同时执行, 作为结果的'step 3'和'step 5'的输出顺序不定。
func example1() {
let semaphore = DispatchSemaphore(value: 0)
print("step 1")
DispatchQueue.global().async {
sleep(2)
print("step 2")
semaphore.signal()
print("step 3")
}
print("step 4")
semaphore.wait()
print("step 5")
}
//example1()
/// 场景2: 线程锁, wait与signal构成了加锁和解锁的要素, 这对函数之间的代码会被保护起来, 不会同时执行。
/// 本场景中, 两个global线程并行执行, 因此'step 10'和'step 20'的输出顺序不定。注意: 先执行'step'的线程, 不一定会先执行wait。
/// 先到达wait的线程, 由于当前信号量为1, 因此可以顺利执行下去, 顺便会将信号量减1。
/// 后到达wait的线程, 由于当前信号量为0, 会阻塞当前线程(后到线程)。
/// 当先线程执行signal后, 会令信号量加1, 于是唤起了后到线程, 后到线程的阻塞状态解除。
func example2() {
let semaphore = DispatchSemaphore(value: 1)
print("step 00")
DispatchQueue.global().async {
sleep(2)
print("step 10")
semaphore.wait()
print("step 11")
sleep(2)
print("step 12")
semaphore.signal()
print("step 13")
}
DispatchQueue.global().async {
sleep(2)
print("step 20")
semaphore.wait()
print("step 21")
sleep(2)
print("step 22")
semaphore.signal()
print("step 23")
}
print("step 01")
}
————————————————
版权声明:本文为CSDN博主「vision66」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/huayu608/article/details/90407175
网友评论