dispatch_semaphore_t
用法,dispatch_semaphore_create
创建信号量实际就是创建的对象设置最大并发数.不得小于0, 小于0导致崩溃,dispatch_semaphore_wait
, 减少一个信号量, 比如创建的对象信号量是5, wait一次就减少一个信号量,信号量变为4, 当信号量为0的时候当前线程就会等待,直到信号量>0的时候才会往下进行.dispatch_semaphore_signal
增加一个信号量,减少与增加信号量是成对出现的.
dispatch_semaphore_t semap = dispatch_semaphore_create(1); // 控制最大并发数1条新线程 此时下面操作是线程安全的
dispatch_semaphore_wait(semap, DISPATCH_TIME_FOREVER);// 此时信号量由1 变为 0 ,即使下面有任务也不会再执行, 因为信号量为0
// 单个线程操作区域... 线程安全
dispatch_semaphore_signal(semap);
- 第一种常见用法
group + queue
使用场景: 单次, 多个任务同时执行, 自动开启多个线程,最后执行完毕在回调处理执行完毕的结果
- 缺点: 不能控制最大并发数, 操作同一资源不安全
// DISPATCH_QUEUE_CONCURRENT 生成一个并发队列(可以有多条线程)
dispatch_queue_t queue = dispatch_queue_create("sendrequest", DISPATCH_QUEUE_CONCURRENT);
// 创建group
dispatch_group_t group = dispatch_group_create();
// 多个耗时任务同时进行 加入group中同时进行,执行完毕监听回调
dispatch_group_async(group, queue, ^{
NSLog(@"1");
sleep(2);
NSLog(@"1+");
});
dispatch_group_async(group, queue, ^{
NSLog(@"2");
});
dispatch_group_async(group, queue, ^{
NSLog(@"3");
});
// group任务全部执行完毕回调
dispatch_group_notify(group, queue, ^{
NSLog(@"done");
});
- 第二种使用场景
semaphore + queue
场景: 多次(有100个任务需要执行, 例如数据库100条数据,需要上传,每条创建一个任务,开2个线程), 控制最大并发数(后台开2个线程), group中不能控制最大并发数, 操作数据线程加锁,保证线程安全
- 缺点不能处理回调
dispatch_semaphore_t semap = dispatch_semaphore_create(2); // 控制最大并发数2条新线程
// DISPATCH_QUEUE_CONCURRENT 生成一个并发队列(可以有多条线程)
dispatch_queue_t queue = dispatch_queue_create("sendrequest", DISPATCH_QUEUE_CONCURRENT);
// 10个任务, 最大并发2,
for (int i = 0; i < 10; i++) {
dispatch_async(queue, ^{
dispatch_semaphore_wait(semap, DISPATCH_TIME_FOREVER);
// 线程操作区域
dispatch_semaphore_signal(semap);
});
}
- 第三种场景组合用法:
dispatch_semaphore_t(设置最大并发数) + dispatch_queue_t(创建并发队列) + dispatch_group_t(监听任务完成回调)
可以处理任务完成回调, 可设置最大并发数
dispatch_semaphore_t semap = dispatch_semaphore_create(2); // 控制最大并发数2条新线程
// DISPATCH_QUEUE_CONCURRENT 生成一个并发队列(可以有多条线程)
dispatch_queue_t queue = dispatch_queue_create("sendrequest", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group = dispatch_group_create();
for (int i = 0; i < 10; i++) {
dispatch_group_async(group, queue, ^{
dispatch_semaphore_wait(semap, DISPATCH_TIME_FOREVER);
// 线程操作区域 最多有两个线程在此做事情
dispatch_semaphore_signal(semap);
});
}
// group任务全部执行完毕回调
dispatch_group_notify(group, queue, ^{
NSLog(@"done");
});