dispatch_semaphore_t
信号量通过计数来控制任务的执行
设置最大的任务量 dispatch_semaphore_create
发送信号任务量+1 dispatch_semaphore_signal
移除信号 任务量-1 dispatch_semaphore_wait
任务量为0的时候会一直等待阻塞所在的线程
信号量的作用
- 将异步线程 保持同步执行
- 线程锁 保证线程的安全
下面结合GCD的知识 我们来模拟一个场景 做个图片上传模块 一共有10张图片 按批次上传 每批次上传三张 1 2 3 同时异步开始上传 下面的等待 上传完的换下个开始上传 依次类推 因为图片上传的不稳定 可以有的上传快 有的上传慢 模拟基于AFNetWorking 上传的任务都是在异步线程完成 AF用的是operationQueue 我们用GCD模拟
//设置最大任务量 3
dispatch_semaphore_t semaphore = dispatch_semaphore_create(3);
//创建并发队列
dispatch_queue_t quene = dispatch_queue_create("yc", DISPATCH_QUEUE_CONCURRENT);
//模拟上传图片的队列
dispatch_queue_t childQuene = dispatch_queue_create("yb", DISPATCH_QUEUE_CONCURRENT);
//创建队列组
dispatch_group_t group = dispatch_group_create();
NSLog(@"线程0=====%@",[NSThread currentThread]);
dispatch_group_async(group,quene, ^{
for (int i = 0; i < 10; i++) {
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
if (i==3) {
dispatch_async(childQuene, ^{
NSLog(@"线程2=====%@",[NSThread currentThread]);
sleep(20);
dispatch_semaphore_signal(semaphore);
NSLog(@"%d号图片已上传",3);
});
}else {
if (i > 3) {
dispatch_group_async(group,childQuene, ^{
NSLog(@"线程3=====%@",[NSThread currentThread]);
NSLog(@"%d号图片正在上传",i);
sleep(2 + i);
dispatch_semaphore_signal(semaphore);
NSLog(@"%d号图片已上传",i);
});
}else {
NSLog(@"线程1=====%@",[NSThread currentThread]);
[NSThread currentThread].name = @"线程1";
dispatch_semaphore_signal(semaphore);
NSLog(@"%d号图片已上传",i);
}
}
}
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"updateUI");
});
线程0=====<NSThread: 0x60000275fc00>{number = 1, name = main}
线程1=====<NSThread: 0x6000027321c0>{number = 3, name = (null)}
0号图片已上传
线程1=====<NSThread: 0x6000027321c0>{number = 3, name = 线程1}
1号图片已上传
线程1=====<NSThread: 0x6000027321c0>{number = 3, name = 线程1}
2号图片已上传
线程2=====<NSThread: 0x600002735780>{number = 4, name = (null)}
线程3=====<NSThread: 0x600002732240>{number = 5, name = (null)}
线程3=====<NSThread: 0x600002734bc0>{number = 6, name = (null)}
5号图片正在上传
4号图片正在上传
4号图片已上传
线程3=====<NSThread: 0x60000272d2c0>{number = 7, name = (null)}
6号图片正在上传
5号图片已上传
线程3=====<NSThread: 0x600002734bc0>{number = 6, name = (null)}
7号图片正在上传
6号图片已上传
线程3=====<NSThread: 0x600002732240>{number = 5, name = (null)}
8号图片正在上传
7号图片已上传
线程3=====<NSThread: 0x6000027321c0>{number = 3, name = 线程1}
9号图片正在上传
3号图片已上传
8号图片已上传
9号图片已上传
updateUI
网友评论