第一、引入
dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSMutableArray *arr=[NSMutableArray new];
for (int i=0; i<100; i++) {
dispatch_async(queue, ^{[arr addObject:[NSNumber numberWithInt:i]];
NSLog(@"the thread is %d",i);
NSLog(@"%@",arr);
});
}
多个线程并发修改数组arr,线程不安全,应该增加安全机制,官方文档:
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html
第二、GCD实现同步的信号量
dispatch_semaphore是GCD的信号量机制,支持三个基本的操作:
dispatch_semaphore_create 创建一个semaphore,可以指定信号量的值
dispatch_semaphore_signal 发送一个信号,信号量加1
dispatch_semaphore_wait 等待信号,当信号总量少于0的时候就会一直等待,否则就可以正常的执行,并让信号总量-1
实例:
int data = 3;
__block int mainData = 0;
__block dispatch_semaphore_t sem = dispatch_semaphore_create(0);
dispatch_queue_t queue = dispatch_queue_create("richard", DISPATCH_QUEUE_PRIORITY_DEFAULT);
dispatch_async(queue, ^(void) {
int sum = 0;
for(int i = 0; i < 5; i++)
{
sum += data;
NSLog(@" Sum: %d", sum);
}
dispatch_semaphore_signal(sem);
});
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
for(int j=0;j<5;j++)
{
mainData++;
NSLog(@">> Main Data: %d",mainData);
}
执行结果:
Sum: 3
Sum: 6
Sum: 9
Sum: 12
Sum: 15
Main Data: 1
Main Data: 2
Main Data: 3
Main Data: 4
Main Data: 5
通过信号量机制保证mainData是在sum后执行
第三、用信号量机制实现同步的实例
针对引言提出的多线程不安全的问题,我们利用信号量机制可以实现一个安全的sample
dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
0);
dispatch_semaphore_t sem=dispatch_semaphore_create(1);
NSMutableArray *arr=[NSMutableArray
new];
for (int i=0; i<20; i++) {
dispatch_async(queue, ^{
dispatch_semaphore_wait(sem,
DISPATCH_TIME_FOREVER);
[arr addObject:[NSNumber
numberWithInt:i]];
NSLog(@"%@",arr);
dispatch_semaphore_signal(sem);
});
}
结果:
2015-02-02 15:15:36.153 testApp[3433:84946] (
0
)
2015-02-02 15:15:36.154 testApp[3433:84946] (
0,
6
)
2015-02-02 15:15:36.155 testApp[3433:84946] (
0,
6,
8
)
2015-02-02 15:15:36.155 testApp[3433:84946] (
0,
6,
8,
10
)
2015-02-02 15:15:36.155 testApp[3433:84946] (
0,
6,
8,
10,
11
)
2015-02-02 15:15:36.155 testApp[3433:84946] (
0,
6,
8,
10,
11,
12
)
2015-02-02 15:15:36.155 testApp[3433:84946] (
0,
6,
8,
10,
11,
12,
14
)
2015-02-02 15:15:36.155 testApp[3433:84946] (
0,
6,
8,
10,
11,
12,
14,
15
)
2015-02-02 15:15:36.156 testApp[3433:84946] (
0,
6,
8,
10,
11,
12,
14,
15,
17
)
2015-02-02 15:15:36.156 testApp[3433:84958] (
0,
6,
8,
10,
11,
12,
14,
15,
17,
18
)
2015-02-02 15:15:36.156 testApp[3433:84948] (
0,
6,
8,
10,
11,
12,
14,
15,
17,
18,
3
)
2015-02-02 15:15:36.156 testApp[3433:84952] (
0,
6,
8,
10,
11,
12,
14,
15,
17,
18,
3,
4
)
2015-02-02 15:15:36.177 testApp[3433:84956] (
0,
6,
8,
10,
11,
12,
14,
15,
17,
18,
3,
4,
13
)
2015-02-02 15:15:36.178 testApp[3433:84953] (
0,
6,
8,
10,
11,
12,
14,
15,
17,
18,
3,
4,
13,
5
)
2015-02-02 15:15:36.178 testApp[3433:84954] (
0,
6,
8,
10,
11,
12,
14,
15,
17,
18,
3,
4,
13,
5,
7
)
2015-02-02 15:15:36.179 testApp[3433:84957] (
0,
6,
8,
10,
11,
12,
14,
15,
17,
18,
3,
4,
13,
5,
7,
16
)
2015-02-02 15:15:36.179 testApp[3433:84947] (
0,
6,
8,
10,
11,
12,
14,
15,
17,
18,
3,
4,
13,
5,
7,
16,
1
)
2015-02-02 15:15:36.179 testApp[3433:84949] (
0,
6,
8,
10,
11,
12,
14,
15,
17,
18,
3,
4,
13,
5,
7,
16,
1,
2
)
2015-02-02 15:15:36.180 testApp[3433:84946] (
0,
6,
8,
10,
11,
12,
14,
15,
17,
18,
3,
4,
13,
5,
7,
16,
1,
2,
19
)
2015-02-02 15:15:36.182 testApp[3433:84955] (
0,
6,
8,
10,
11,
12,
14,
15,
17,
18,
3,
4,
13,
5,
7,
16,
1,
2,
19,
9
)