文章目录
  1. 1. 创建一个信号量
  2. 2. 提高信号量
  3. 3. 等待降低信号量
  4. 4. 举例分析

dispatch_semaphore(信号量)就是控制访问资源的数量,比如系统有两个资源可以被利用,同时有三个线程要访问,只能允许两个线程访问,第三个应当等待资源被释放后再访问。

注意:在GCD中,只有调度的线程在信号量不足的时候才会进入内核态进行线程阻塞

创建一个信号量

1
func dispatch_semaphore_create(_ value: Int) -> dispatch_semaphore_t !

其中value为信号量的初值,如果小于0则会返回NULL

提高信号量

1
func dispatch_semaphore_signal(_ dsema: dispatch_semaphore_t!) -> Int

等待降低信号量

1
2
func dispatch_semaphore_wait(_ dsema: dispatch_semaphore_t!,
_ timeout: dispatch_time_t) -> Int

注意:正常的使用顺序是先降低然后再提高,这两个函数通常成对使用。

举例分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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)
}
}

这段代码模拟提交三个任务,提交到全局队列(并行队列)

当信号量的初始值为 2 时候:

1
2
3
4
5
6
2015-08-10 17:42:01.963 TestExample[632:11631] First task starting
2015-08-10 17:42:01.964 TestExample[632:11630] Second task starting
2015-08-10 17:42:02.971 TestExample[632:11630] Second task is done
2015-08-10 17:42:02.971 TestExample[632:11631] First task is done
2015-08-10 17:42:02.971 TestExample[632:11633] Thrid task starting
2015-08-10 17:42:03.974 TestExample[632:11633] Thrid task is done

当信号量的初始值为 3 时候:

1
2
3
4
5
6
2015-08-10 17:42:49.912 TestExample[666:12259] First task starting
2015-08-10 17:42:49.912 TestExample[666:12258] Second task starting
2015-08-10 17:42:49.912 TestExample[666:12260] Thrid task starting
2015-08-10 17:42:50.915 TestExample[666:12259] First task is done
2015-08-10 17:42:50.915 TestExample[666:12260] Thrid task is done
2015-08-10 17:42:50.915 TestExample[666:12258] Second task is done

当信号量的初始值为 1 时候:

1
2
3
4
5
6
2015-08-10 17:43:35.140 TestExample[694:12768] First task starting
2015-08-10 17:43:36.145 TestExample[694:12768] First task is done
2015-08-10 17:43:36.145 TestExample[694:12771] Second task starting
2015-08-10 17:43:37.146 TestExample[694:12771] Second task is done
2015-08-10 17:43:37.146 TestExample[694:12769] Thrid task starting
2015-08-10 17:43:38.150 TestExample[694:12769] Thrid task is done