dispatch_semaphore信号量是GCD用来同步的一种方式。
信号量通常用在 允许几个线程同时访问一个资源,通过信号量来控制访问的线程个数.
与他相关的共有三个函数,分别是
dispatch_semaphore_create,dispatch_semaphore_signal,dispatch_semaphore_wait。
(1)dispatch_semaphore_create的声明为:
dispatch_semaphore_t dispatch_semaphore_create(long value);
其中value为信号量的初值,如果小于0则会返回NULL ,返回dispatch_semaphore_t类型的信号量。
(2)dispatch_semaphore_signal的声明为:
long dispatch_semaphore_signal(dispatch_semaphore_t dsema)
提高信号量,使传入的信号量的值加1;
返回值为long类型,
当返回值为0时,表示当前 已经没有线程等待其处理 (的信号量)
当返回值不为0时,表示其当前 有(一个或多个)线程等待其处理(的信号量),并唤醒一 个等待的线程注:(当线程有优先级时,唤醒优先级最高的线程;否则随机唤醒,线程一级一级的唤醒,直到返回0)
(3) dispatch_semaphore_wait的声明为:
long dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);
等待降低信号量,使传入的信号量的值减1;
返回值为long类型,
当返回值为0时 表示在timeout(时间长度)之前,该函数所处的线程被成功唤醒。
当其返回不为0时,表示阻塞线程 timeout时间。
函数的作用: 如果信号量的值大于0,该线程就继续执行下面的语句
如果信号量的值为0,那么阻塞当前线程 等待timeout(时间长度)
(注意timeout的类型为dispatch_time_t,不能直接传入整形或float型数)。
注:在设置timeout时,比较有用的两个宏:DISPATCH_TIME_NOW 和 DISPATCH_TIME_FOREVER。
DISPATCH_TIME_NOW 表示当前;
DISPATCH_TIME_FOREVER 表示遥远的未来;
举例分析
<pre name="code" class="objc">//
// ViewController.swift
// SwiftTestExample
//
// Created by huangwenchen on 15/1/6.
// Copyright (c) 2015年 huangwenchen. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
var semaphore:dispatch_semaphore_t;
required init(coder aDecoder: NSCoder) {
self.semaphore = dispatch_semaphore_create(1)
super.init(coder: aDecoder)
}
override func viewDidLoad() {
super.viewDidLoad()
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), {() -> Void in
self.task_first()
})
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), { () -> Void in
self.task_second()
})
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), { () -> Void in
self.task_third()
})
// Do any additional setup after loading the view, typically from a nib.
}
func task_first(){
dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER)
NSLog("%@","First task starting")
sleep(1)
NSLog("%@", "First task is done")
dispatch_semaphore_signal(self.semaphore)
}
func task_second(){
dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER)
NSLog("%@","Second task starting")
sleep(1)
NSLog("%@", "Second task is done")
dispatch_semaphore_signal(self.semaphore)
}
func task_third(){
dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER)
NSLog("%@","Thrid task starting")
sleep(1)
NSLog("%@", "Thrid task is done")
dispatch_semaphore_signal(self.semaphore)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
这段代码模拟提交三个任务,提交到全局队列(并行队列)
当信号量的初初始为2时候
输出
2015-01-06 19:42:01.963 SwiftTestExample[632:11631] First task starting
2015-01-06 19:42:01.964 SwiftTestExample[632:11630] Second task starting
2015-01-06 19:42:02.971 SwiftTestExample[632:11630] Second task is done
2015-01-06 19:42:02.971 SwiftTestExample[632:11631] First task is done
2015-01-06 19:42:02.971 SwiftTestExample[632:11633] Thrid task starting
2015-01-06 19:42:03.974 SwiftTestExample[632:11633] Thrid task is done
当信号量为3的时候
2015-01-06 19:42:49.912 SwiftTestExample[666:12259] First task starting
2015-01-06 19:42:49.912 SwiftTestExample[666:12258] Second task starting
2015-01-06 19:42:49.912 SwiftTestExample[666:12260] Thrid task starting
2015-01-06 19:42:50.915 SwiftTestExample[666:12259] First task is done
2015-01-06 19:42:50.915 SwiftTestExample[666:12260] Thrid task is done
2015-01-06 19:42:50.915 SwiftTestExample[666:12258] Second task is done
当信号量为1的时候
2015-01-06 19:43:35.140 SwiftTestExample[694:12768] First task starting
2015-01-06 19:43:36.145 SwiftTestExample[694:12768] First task is done
2015-01-06 19:43:36.145 SwiftTestExample[694:12771] Second task starting
2015-01-06 19:43:37.146 SwiftTestExample[694:12771] Second task is done
2015-01-06 19:43:37.146 SwiftTestExample[694:12769] Thrid task starting
2015-01-06 19:43:38.150 SwiftTestExample[694:12769] Thrid task is done