iOS开发技能

dispatch_semaphore使用场景

2017-12-20  本文已影响33人  nero_i

一、定义

二、使用场景1

假设现在系统有两个空闲资源可以被利用,但同一时间却有三个线程要进行访问,这种情况下,该如何处理呢?

     //crate的value表示,最多几个资源可访问
    dispatch_semaphore_t samphore = dispatch_semaphore_create(2);
    dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //dispatch_queue_t quene = dispatch_queue_create("com.anji.jiajia", DISPATCH_QUEUE_CONCURRENT);
    
    //任务1
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(samphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 1");
        sleep(1);
        NSLog(@"completed task 1");
        dispatch_semaphore_signal(samphore);
    });
    
    //任务2
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(samphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 2");
        sleep(1);
        NSLog(@"completed task 2");
        dispatch_semaphore_signal(samphore);
    });
    
    //任务3
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(samphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 3");
        sleep(1);
        NSLog(@"completed task 3");
        dispatch_semaphore_signal(samphore);
    });

运行结果:

2017-12-20 13:35:34.308282+0800 OCDemo[61949:15613320] run task 1
2017-12-20 13:35:34.308291+0800 OCDemo[61949:15613317] run task 2
2017-12-20 13:35:35.310784+0800 OCDemo[61949:15613320] completed task 1
2017-12-20 13:35:35.310784+0800 OCDemo[61949:15613317] completed task 2
2017-12-20 13:35:35.311016+0800 OCDemo[61949:15613319] run task 3
2017-12-20 13:35:36.313924+0800 OCDemo[61949:15613319] completed task 3

三、使用场景2

我们要下载很多图片,并发异步进行,每个下载都会开辟一个新线程,可是我们又担心太多线程肯定cpu吃不消,那么我们这里也可以用信号量控制一下最大开辟线程数。

 //crate的value表示,最多几个资源可访问
dispatch_semaphore_t samphore = dispatch_semaphore_create(5);
dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
for (int i = 0; i < 15; i++) {
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(samphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task %d", i);
        [self downloadImge:^(BOOL isSuccess, NSString *errorMsg) {
            NSLog(@"BLock completed %d", i);
            dispatch_semaphore_signal(samphore);
        }];
    });
}

由于是异步执行的,所以每次循环Block就会执行dispatch_semaphore_wait,从而semaphore-1.当循环5次后semaphore==0,则会阻塞线程,直到执行了Block的dispatch_semaphore_signal 才会继续执行。

四、使用场景3

在开发中我们需要处理下载多张照片等待所有网络回调完之后才执行后面的操作。或者等待多个网络请求,所有请求成功后数据融合处理。

 //crate的value表示,最多几个资源可访问
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

for (int i = 0; i < 5; i++) {
    dispatch_group_async(group, quene, ^{
        dispatch_semaphore_t samphore = dispatch_semaphore_create(0);
        [self downloadImge:^(BOOL isSuccess, NSString *errorMsg) {
            NSLog(@"task %d completed ", i);
            dispatch_semaphore_signal(samphore);
        }];
        dispatch_semaphore_wait(samphore, DISPATCH_TIME_FOREVER);
    });
}

dispatch_group_notify(group, quene, ^{
    NSLog(@"All task completed ====");
});

运行结果:

2017-12-20 14:22:03.162137+0800 OCDemo[64177:15790354] task 0 completed
2017-12-20 14:22:03.162138+0800 OCDemo[64177:15790351] task 3 completed
2017-12-20 14:22:04.165827+0800 OCDemo[64177:15790352] task 2 completed
2017-12-20 14:22:05.167003+0800 OCDemo[64177:15790368] task 4 completed
2017-12-20 14:22:05.166964+0800 OCDemo[64177:15790353] task 1 completed
2017-12-20 14:22:05.167153+0800 OCDemo[64177:15790368] All task completed ====

swift:DispatchSemaphore
GCD信号量

上一篇下一篇

猜你喜欢

热点阅读