美文网首页
2019-09-27

2019-09-27

作者: 某某cp | 来源:发表于2019-09-29 09:10 被阅读0次

iOS信号量

信号量的本质:

信号量的本质是数据操作锁, 它本身不具有数据交换的功能,而是通过控制其他的通信资源来实现进程间通信,它本身只是一种外部资源的标识。信号量在此过程中负责数据操作的互斥、同步等功能.

信号量的工作原理

由于信号量只能进行两种操作等待和发送信号,即P(sv)和V(sv),他们的行为是这样的:

P(sv):如果sv的值大于零,就给它减1;如果它的值为零,就挂起该进程的执行

V(sv):如果有其他进程因等待sv而被挂起,就让它恢复运行,如果没有进程因等待sv而挂起,就给它加1.

举个例子,就是 两个进程共享信号量sv,一旦其中一个进程执行了P(sv)操作,它将得到信号量,并可以进入临界区,使sv减1。而第二个进程将被阻止进入临界区,因为 当它试图执行P(sv)时,sv为0,它会被挂起以等待第一个进程离开临界区域并执行V(sv)释放信号量,这时第二个进程就可以恢复执行。

信号量的三个函数是:

dispatch_semaphore_create(long value); // 创建一个semaphore
dispatch_semaphore_signal(dispatch_semaphore_t dsema); // 发送一个信号
dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout); // 等到信号

举几个例子,代码如下:

-(void)dispatch_group_function1
{
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, dispatch_queue_create("com.dispatch.test", DISPATCH_QUEUE_CONCURRENT), ^{
        NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.baidu.com"]];
        NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            // 请求完成,可以通知界面刷新界面等操作
            NSLog(@"第一步网络请求完成");
            // 使信号的信号量+1,这里的信号量本来为0,+1信号量为1(绿灯)
            dispatch_semaphore_signal(semaphore);
        }];
        [task resume];
        // 以下还要进行一些其他的耗时操作
        NSLog(@"耗时操作1继续进行");
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    });
    dispatch_group_async(group, dispatch_queue_create("com.dispatch.test", DISPATCH_QUEUE_CONCURRENT), ^{
        NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.github.com"]];
        NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            // 请求完成,可以通知界面刷新界面等操作
            NSLog(@"第二步网络请求完成");
            // 使信号的信号量+1,这里的信号量本来为0,+1信号量为1(绿灯)
            dispatch_semaphore_signal(semaphore);
        }];
        [task resume];
        // 以下还要进行一些其他的耗时操作
        NSLog(@"耗时操作2继续进行");
        dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);
    });
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"刷新界面等在主线程的操作");
    });
}

首先,默认初始值给的信号量值未0,所以线程1和线程2的执行上其实是没有顺序的,但是,由于在这里设置了dispatch_semaphore_wait,并且当前的信号量值未0,所以会堵塞线程,直到执行了dispatch_semaphore_signal信号量+1,才会继续执行之后的线程操作,打印结果为:

2019-09-27 15:02:51.420389+0800 CPTestDemo[5253:337990] 耗时操作2继续进行
2019-09-27 15:02:51.420414+0800 CPTestDemo[5253:337992] 耗时操作1继续进行
2019-09-27 15:02:51.544547+0800 CPTestDemo[5253:338000] 第一步网络请求完成
2019-09-27 15:02:53.100889+0800 CPTestDemo[5253:337995] 第二步网络请求完成
2019-09-27 15:02:53.101065+0800 CPTestDemo[5253:337950] 刷新界面等在主线程的操作

如果初始值设置dispatch_semaphore_create(1),又会是怎样的结果的

2019-09-27 15:05:34.816451+0800 CPTestDemo[5302:345432] 耗时操作1继续进行
2019-09-27 15:05:34.816451+0800 CPTestDemo[5302:345433] 耗时操作2继续进行
2019-09-27 15:05:34.926754+0800 CPTestDemo[5302:345437] 第一步网络请求完成
2019-09-27 15:05:34.926966+0800 CPTestDemo[5302:345393] 刷新界面等在主线程的操作
2019-09-27 15:05:36.475560+0800 CPTestDemo[5302:345437] 第二步网络请求完成

如果初始值设置dispatch_semaphore_create(2)呢

2019-09-27 15:27:59.737338+0800 CPTestDemo[5587:373223] 耗时操作1继续进行
2019-09-27 15:27:59.737338+0800 CPTestDemo[5587:373222] 耗时操作2继续进行
2019-09-27 15:27:59.758308+0800 CPTestDemo[5587:373190] 刷新界面等在主线程的操作
2019-09-27 15:27:59.880029+0800 CPTestDemo[5587:373220] 第一步网络请求完成
2019-09-27 15:28:01.847547+0800 CPTestDemo[5587:373220] 第二步网络请求完成

因为信号量初始值为2,线程1和2都会执行,由于执行完成信号量减为0,但是组中的任务已经执行完了,所以会接着执行dispatch_group_notify,然后依次是第一步网络请求和第二步网络请求

相关文章

  • 九曲里

    ?南湖九曲里??2019-09-27~28

  • 温习:卖场设计的一些基本原则和底层逻辑

    顾客为什么购买?卖场设计原理的底层逻辑 佛度海生 字数 16910 · 阅读 1009 2019-09-27 02...

  • 算法公开课 1 课程简介及插入排序算法分析

    2019-09-27视频来自B站,以下笔记记录视频学习点及不懂点。原创By bellaSun 1. Inserti...

  • 2019-09-29

    2019-09-28 2019-09-27 今夜随笔 今天晚上路过一家超市,索性就进去买点东西。刚进去就听...

  • 断掉的坚持:写日志

    2019-09-27,编号518从2018年6月1日开始立flag要坚持写1000天的文章,然后即使中间经历了跳槽...

  • 华为IPD-全面需求管理

    占华为研发人员5%的产品管理部,为何成为产品线的“大脑”? 来源:创越战略观察 2019-09-27 22:35 ...

  • 人生应该负重前行

    张波280669736 2019-09-27 15:13:24 人大多数对自己的一生没有规划,没有目标,特别是一些...

  • 家长上岗证——道德人格家教学

    青岛道德书院理子 2019-09-27 15:52:55 有幸看到了皇甫军伟先生的短视频家教演讲,与我一直倡导的道...

  • 邀饮二首

    同窗李良重君邀饮自家园林 硕果累金枝,鸡肥豕壮时。 西村沽美酒,呼取醉东篱。 2019-09-27 今天中午诗友又...

  • 秋风和初恋

    2019-09-27 当秋风吹乱你头发的时候 一定不要躲 迎上去吧 接受它的亲吻 热烈又毫无规章 秋天啊秋天 让人...

网友评论

      本文标题:2019-09-27

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