GCD全解-07-dispatch_semaphore-信号量/数据同步

GCD系列是阅读官方文件和在实践中总结的一些常见的GCD用法,基本涉及全部的GCD内容形成的集合文章,文章重点在与精简和全面覆盖。

学习本集合你可以了解:
1. GCD是如何做到多线程调度的
2. 对比其他iOS的多线程方案,GCD的优势和劣势
3. 如何使用GCD相关的API

我将在后续不断补充详细内容和实际案例, 欢迎关注,提问和讨论

01-dispatch-iOS系统调度

02-dispatch_queue-调度队列

03-dispatch_after/dispatch_time-延迟调度和操作

04-dispatch_barrier_sync/async-线程阻塞

05-dispatch_apply-重复提交操作

06-dispatch_once-单次执行

07-dispatch_semaphore-信号量/数据同步

08-dispatch_group-调度组/多异步操作控制

09-dispatch_block-GCD取消操作

10-dispatch_source-调度资源

11-GCD死锁

主要API列表
dispatch_semaphore_create   创建一个semaphore
dispatch_semaphore_signal   发送一个信号
dispatch_semaphore_wait    等待信号

如何在GCD中快速的控制并发呢?
信号量是一个整形值并且具有一个初始计数值,并且支持两个操作:信号通知和等待。
当一个信号量被信号通知,其计数会被增加。当一个线程在一个信号量上等待时,线程会被阻塞(如果有必要的话),直至计数器大于零,然后线程会减少这个计数。

dispatch_semaphore_create

 Creates new counting semaphore with an initial value.
 *
 * @discussion
 * Passing zero for the value is useful for when two threads need to reconcile
 * the completion of a particular event. Passing a value greater than zero is
 * useful for managing a finite pool of resources, where the pool size is equal
 * to the value.
 *
 * @param value
 * The starting value for the semaphore. Passing a value less than zero will
 * cause NULL to be returned.

dispatch_semaphore_t dispatch_semaphore_create(long value);

dispatch_semaphore_wait

Wait (decrement) for a semaphore.
    当信号总量少于0的时候就会一直等待,否则就可以正常的执行,并让信号总量-1,
 * @discussion
 * Decrement the counting semaphore. If the resulting value is less than zero,
 * this function waits for a signal to occur before returning.
 *
 * @param timeout
 * When to timeout (see dispatch_time). As a convenience, there are the
 * DISPATCH_TIME_NOW and DISPATCH_TIME_FOREVER constants.

long dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);

dispatch_semaphore_signal

Signal (increment) a semaphore.
 * @discussion
 * Increment the counting semaphore. If the previous value was less than zero,
 * this function wakes a waiting thread before returning.

long dispatch_semaphore_signal(dispatch_semaphore_t dsema);

demo

为了确保 信号先发送再接受,
就可以使用信号量创建的时候为0, 表示当前的资源不可使用,
当并发执行第二个block的时候发现需要等待信号量为1. 所以暂时线程不执行
而第一个block是不需要等待信号的.于是先执行第一个block,并且发送一个信号.于是第二个等待执行的block会执行.
此时因为当前第一个block尚未执行完毕,那么此时两个block将会交替执行
换句话说: 如果block发送信号注释掉不执行 dispatch_semaphore_signal(semaphore);那么block2就不会打印信号已接受就没有下文了

- (void)viewWillAppear:(BOOL)animated {
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"信号已发送");
        dispatch_semaphore_signal(semaphore);
        for (int i = 0; i < 10; i++) {
            NSLog(@"%i", i);
        }
    });
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"信号已接受");
        for (int i = 0; i < 10; i++) {
            NSLog(@"第二个block%i", i);
        }
    });
}


2016-11-05 16:41:34.529 Multithreading[15864:468169] 信号已发送
2016-11-05 16:41:34.529 Multithreading[15864:468185] 信号已接受
2016-11-05 16:41:34.529 Multithreading[15864:468169] 0
2016-11-05 16:41:34.529 Multithreading[15864:468185] 第二个block0
2016-11-05 16:41:34.529 Multithreading[15864:468185] 第二个block1
2016-11-05 16:41:34.529 Multithreading[15864:468169] 1
2016-11-05 16:41:34.529 Multithreading[15864:468185] 第二个block2
2016-11-05 16:41:34.530 Multithreading[15864:468169] 2
2016-11-05 16:41:34.530 Multithreading[15864:468185] 第二个block3
2016-11-05 16:41:34.530 Multithreading[15864:468169] 3
2016-11-05 16:41:34.530 Multithreading[15864:468185] 第二个block4
2016-11-05 16:41:34.530 Multithreading[15864:468169] 4
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值