GCD信号量(dispatch_semaphore)

上一讲我们谈到可以使用GCD调度组来实现异步处理完成后最后回到某个线程后集中处理(多接口异步请求.回到主线程刷新UI).戳:GCD调度组(dispatch_group)

这一讲我们来谈一个也能实现该需求的GCD信号量(Semaphores)

主要就是下面几个东西

//    dispatch_semaphore_t

//    dispatch_semaphore_create(<#long value#>)
//    dispatch_semaphore_wait(<#dispatch_semaphore_t  _Nonnull dsema#>, <#dispatch_time_t timeout#>)
//    dispatch_semaphore_signal(<#dispatch_semaphore_t  _Nonnull dsema#>)
1.dispatch_semaphore_t

dispatch_semaphore_t类似于dispatch_group_t这种东西就行.创建一个信号量就返回这个东西

2.创建函数

dispatch_semaphore_create(<#long value#>)传入一个long类型数据.返回一个dispatch_semaphore_t.但是这个long类型的数据不能小于0,小于0的话会返回NULL.

3.等待降低信号量
//    dispatch_semaphore_wait(<#dispatch_semaphore_t  _Nonnull dsema#>, <#dispatch_time_t timeout#>)

这个先后顺序并不好描述.因为从代码上下结构来看的话.肯定是先写的提高信号量,然而在执行顺序上来说的话那就是降低信号量在前.

4.提高信号量
//    dispatch_semaphore_signal(<#dispatch_semaphore_t  _Nonnull dsema#>)

提高信号量可以让与之成对的wait失效.然后继续往下执行.
他有一个long类型的返回值,当没有wait的时候就会返回0.

注意:信号量和调度组不一样,需要先降低信号量,然后再提高.如果不成对出现可能会出现EXC_BAD_INSTRUCTION错误,如果先降低信号量(wait)那么就可能导致代码卡死

使用用例

/// 测试 GCD Semaphores
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

dispatch_async(dispatch_get_global_queue(0, 0), ^{
	NSLog(@"1");
	dispatch_semaphore_signal(semaphore);
});
NSLog(@"5");
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"6");

dispatch_async(dispatch_get_global_queue(0, 0), ^{
	NSLog(@"2");
	dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

dispatch_async(dispatch_get_global_queue(0, 0), ^{
	NSLog(@"3");
	dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

NSLog(@"4");

输出结果的话是516234

对于多线程有关的东西的话,还是得多次测试才能得出正确结论

加个延时测试一下

    /// 测试 GCD Semaphores
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [NSThread sleepForTimeInterval:2];
        NSLog(@"1");
        dispatch_semaphore_signal(semaphore);
    });
    NSLog(@"5");
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    NSLog(@"6");

    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [NSThread sleepForTimeInterval:2];
        NSLog(@"2");
        dispatch_semaphore_signal(semaphore);
    });
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [NSThread sleepForTimeInterval:2];
        NSLog(@"3");
        dispatch_semaphore_signal(semaphore);
    });
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

    NSLog(@"4");

输出结果还是5.1.6.2.3.4

那么就是.一直顺序执行.如果碰到了dispatch_semaphore_wait.他就会等到接收到signal信号量才会往下走.或者是等到wait的第二个参数(最大等待时间)达到(也算是收到了一个信号量吧).所以必须得在wait之前写下异步任务并且一定能发送出singal信号,或者有最大等待时间.不然会卡死.(直接wait的话线程阻塞.下面不会走.异步任务开在下面等于没开),

GCD的semaphore比较适合用于多个任务需要按某种顺序执行

/// 测试 GCD Semaphores
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

dispatch_async(dispatch_get_global_queue(0, 0), ^{
	[NSThread sleepForTimeInterval:2];
	NSLog(@"1");
	long longValue = dispatch_semaphore_signal(semaphore);
	NSLog(@"1.longValue:%ld" ,longValue);
});

dispatch_async(dispatch_get_global_queue(0, 0), ^{
	[NSThread sleepForTimeInterval:1];
	NSLog(@"2");
	long longValue = dispatch_semaphore_signal(semaphore);
	NSLog(@"2.longValue:%ld" ,longValue);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

dispatch_async(dispatch_get_global_queue(0, 0), ^{
	[NSThread sleepForTimeInterval:2];
	NSLog(@"3");
	long longValue = dispatch_semaphore_signal(semaphore);
	NSLog(@"3.longValue:%ld" ,longValue);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

NSLog(@"4");

如果是上面这种的话,1和2的打印顺序就不一定了.所以说GCD Semaphores很适合用于定制任务执行顺序.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值