美文网首页iOS Developer
关于 semaphore 信号量

关于 semaphore 信号量

作者: sea777777 | 来源:发表于2016-11-02 14:52 被阅读239次

    dispatch_semaphore 信号量基于计数器的一种多线程同步机制。在多个线程访问共有资源时候,会因为多线程的特性而引发数据出错的问题。

    和普通锁不一样,这个可以精细的控制并发量;

    dispatch_semaphore_t semaphore = dispatch_semaphore_create(3);
    会创建三个信号量
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    每次wait都会消耗一个信号量,等待时间可以设置,这里设置为一直等待,如果当前信号量(semaphore)小于1,则一直等待
    dispatch_semaphore_signal(semaphore);
    发送信号量,发送一次,信号量+1

    下面的demo可以并发执行 ,但每次只能并发3个线程;
    因为消耗3次信号量后,就进入等待状态,直到sleep 2s完成后,会发送信号量dispatch_semaphore_signal
    然后继续执行;

    所以每次输出3个,直到循环完成;

    dispatch_group_t group = dispatch_group_create();
     dispatch_semaphore_t semaphore = dispatch_semaphore_create(3);
     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
     for (int i = 0; i < 90; i++)
     {
     dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
     dispatch_group_async(group, queue, ^{
     NSLog(@"%i",i);
     sleep(2);
     dispatch_semaphore_signal(semaphore);
     });
     }
    
    2016-11-02 14:37:30.293 PopTipDemo[7860:655041] 2
    2016-11-02 14:37:30.293 PopTipDemo[7860:655022] 1
    2016-11-02 14:37:30.293 PopTipDemo[7860:655032] 0
    2016-11-02 14:37:32.295 PopTipDemo[7860:655022] 3
    2016-11-02 14:37:32.295 PopTipDemo[7860:655032] 4
    2016-11-02 14:37:32.295 PopTipDemo[7860:655041] 5
    2016-11-02 14:37:34.297 PopTipDemo[7860:655041] 6
    2016-11-02 14:37:34.297 PopTipDemo[7860:655022] 7
    2016-11-02 14:37:34.297 PopTipDemo[7860:655032] 8
    2016-11-02 14:37:36.299 PopTipDemo[7860:655041] 9
    2016-11-02 14:37:36.302 PopTipDemo[7860:655022] 10
    2016-11-02 14:37:36.302 PopTipDemo[7860:655032] 11
    2016-11-02 14:37:38.303 PopTipDemo[7860:655041] 12
    2016-11-02 14:37:38.303 PopTipDemo[7860:655022] 13
    2016-11-02 14:37:38.303 PopTipDemo[7860:655032] 14
    2016-11-02 14:37:40.308 PopTipDemo[7860:655032] 17
    2016-11-02 14:37:40.308 PopTipDemo[7860:655041] 15
    2016-11-02 14:37:40.308 PopTipDemo[7860:655022] 16
    2016-11-02 14:37:42.310 PopTipDemo[7860:655032] 19
    2016-11-02 14:37:42.310 PopTipDemo[7860:655022] 18
    2016-11-02 14:37:42.310 PopTipDemo[7860:655041] 20
    2016-11-02 14:37:44.313 PopTipDemo[7860:655032] 23
    2016-11-02 14:37:44.313 PopTipDemo[7860:655022] 22
    2016-11-02 14:37:44.313 PopTipDemo[7860:655041] 21
    2016-11-02 14:37:46.316 PopTipDemo[7860:655032] 24
    2016-11-02 14:37:46.316 PopTipDemo[7860:655041] 26
    2016-11-02 14:37:46.316 PopTipDemo[7860:655022] 25
    2016-11-02 14:37:48.318 PopTipDemo[7860:655032] 29
    2016-11-02 14:37:48.318 PopTipDemo[7860:655041] 28
    2016-11-02 14:37:48.318 PopTipDemo[7860:655022] 27
    2016-11-02 14:37:50.319 PopTipDemo[7860:655032] 31
    2016-11-02 14:37:50.319 PopTipDemo[7860:655022] 32
    2016-11-02 14:37:50.319 PopTipDemo[7860:655041] 30
    2016-11-02 14:37:52.323 PopTipDemo[7860:655041] 35
    2016-11-02 14:37:52.323 PopTipDemo[7860:655032] 33
    2016-11-02 14:37:52.323 PopTipDemo[7860:655022] 34
    2016-11-02 14:37:54.324 PopTipDemo[7860:655032] 36
    2016-11-02 14:37:54.324 PopTipDemo[7860:655022] 37
    2016-11-02 14:37:54.324 PopTipDemo[7860:655041] 38
    2016-11-02 14:37:56.327 PopTipDemo[7860:655022] 39
    2016-11-02 14:37:56.327 PopTipDemo[7860:655032] 40
    2016-11-02 14:37:56.327 PopTipDemo[7860:655041] 41
    2016-11-02 14:37:58.331 PopTipDemo[7860:655022] 42
    2016-11-02 14:37:58.331 PopTipDemo[7860:655032] 43
    2016-11-02 14:37:58.331 PopTipDemo[7860:655041] 44
    2016-11-02 14:38:00.335 PopTipDemo[7860:655041] 45
    2016-11-02 14:38:00.335 PopTipDemo[7860:655032] 46
    2016-11-02 14:38:00.335 PopTipDemo[7860:655022] 47
    2016-11-02 14:38:02.336 PopTipDemo[7860:655022] 48
    2016-11-02 14:38:02.336 PopTipDemo[7860:655032] 49
    2016-11-02 14:38:02.336 PopTipDemo[7860:655041] 50
    2016-11-02 14:38:04.339 PopTipDemo[7860:655022] 52
    2016-11-02 14:38:04.339 PopTipDemo[7860:655032] 51
    2016-11-02 14:38:04.339 PopTipDemo[7860:655041] 53
    2016-11-02 14:38:06.343 PopTipDemo[7860:655022] 56
    2016-11-02 14:38:06.343 PopTipDemo[7860:655032] 55
    2016-11-02 14:38:06.344 PopTipDemo[7860:655041] 54
    2016-11-02 14:38:08.346 PopTipDemo[7860:655022] 57
    2016-11-02 14:38:08.346 PopTipDemo[7860:655041] 58
    2016-11-02 14:38:08.346 PopTipDemo[7860:655032] 59
    2016-11-02 14:38:10.351 PopTipDemo[7860:655022] 60
    2016-11-02 14:38:10.351 PopTipDemo[7860:655041] 61
    2016-11-02 14:38:10.351 PopTipDemo[7860:655032] 62
    2016-11-02 14:38:12.352 PopTipDemo[7860:655022] 64
    2016-11-02 14:38:12.352 PopTipDemo[7860:655041] 63
    2016-11-02 14:38:12.357 PopTipDemo[7860:655032] 65
    2016-11-02 14:38:14.354 PopTipDemo[7860:655041] 66
    2016-11-02 14:38:14.354 PopTipDemo[7860:655022] 67
    2016-11-02 14:38:14.363 PopTipDemo[7860:655444] 68
    2016-11-02 14:38:16.356 PopTipDemo[7860:655022] 69
    2016-11-02 14:38:16.356 PopTipDemo[7860:655041] 70
    2016-11-02 14:38:16.368 PopTipDemo[7860:655444] 71
    2016-11-02 14:38:18.359 PopTipDemo[7860:655022] 73
    2016-11-02 14:38:18.359 PopTipDemo[7860:655041] 72
    2016-11-02 14:38:18.371 PopTipDemo[7860:655444] 74
    2016-11-02 14:38:20.360 PopTipDemo[7860:655041] 75
    2016-11-02 14:38:20.360 PopTipDemo[7860:655022] 76
    2016-11-02 14:38:20.376 PopTipDemo[7860:655444] 77
    2016-11-02 14:38:22.363 PopTipDemo[7860:655022] 79
    2016-11-02 14:38:22.363 PopTipDemo[7860:655041] 78
    2016-11-02 14:38:22.380 PopTipDemo[7860:655032] 80
    2016-11-02 14:38:24.369 PopTipDemo[7860:655041] 81
    2016-11-02 14:38:24.369 PopTipDemo[7860:655022] 82
    2016-11-02 14:38:24.386 PopTipDemo[7860:655444] 83
    2016-11-02 14:38:26.375 PopTipDemo[7860:655041] 85
    2016-11-02 14:38:26.375 PopTipDemo[7860:655022] 84
    2016-11-02 14:38:26.389 PopTipDemo[7860:655444] 86
    
    
    dispatch_semaphore_t semaphore =  dispatch_semaphore_create(0);
        
        [[[NSURLSession sharedSession] downloadTaskWithURL:[NSURL URLWithString:@"http://xxxxxx.com"]
                                        completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error)
        {
    
            //下载完后会发送一个信号量
            dispatch_semaphore_signal(semaphore);
            
        }] resume];
        
        //设置超时时间
        double timeout      = 5;
        dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, timeout*NSEC_PER_SEC);
        
        //这里会等待,如果5秒内下载完成,会执行下去,返回0
        //如果5秒没下载完成,也不会继续等待下去,但是返回值不为0
        long result         = dispatch_semaphore_wait(semaphore, time);
        
        NSLog(@"result:----%ld",result);
    
    • 上面一段代码可以控制多个下载任务的并发数量,并且可以通过 dispatch_semaphore_wait 可以对任务进行超时操作;
      信号量属于底层工具,很强大,性能很高;
    Paste_Image.png
    • 第一个是自旋锁,苹果发现这个是有个bug,高级锁和低级锁争夺资源的时候会很消耗性能,所以已经很少用了,那么信号量作为锁来说性能是最高了;

    相关文章

      网友评论

        本文标题:关于 semaphore 信号量

        本文链接:https://www.haomeiwen.com/subject/sfivuttx.html