美文网首页
2019-08-30

2019-08-30

作者: bacon_iOS | 来源:发表于2019-11-19 19:22 被阅读0次

前几天,同事多线程访问sqlite的时候遇到一个问题,我也跟着看了一下,这几天又刚好看了一些相关的博文,发现一个问题,所以在此记录一下。

先展示代码如下:

    dispatch_queue_t q = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
    for (NSUInteger i = 0; i < 10; i++) {
        
    }

以下是日志打印

2019-08-30 16:34:39.999006+0800 odinDomain[57322:1491164] current thread = <NSThread: 0x600000464a80>{number = 5, name = (null)}, index = 0
2019-08-30 16:34:39.999211+0800 odinDomain[57322:1491164] current thread = <NSThread: 0x600000464a80>{number = 5, name = (null)}, index = 1
2019-08-30 16:34:39.999977+0800 odinDomain[57322:1491164] current thread = <NSThread: 0x600000464a80>{number = 5, name = (null)}, index = 2
2019-08-30 16:34:40.000368+0800 odinDomain[57322:1491164] current thread = <NSThread: 0x600000464a80>{number = 5, name = (null)}, index = 3
2019-08-30 16:34:40.001670+0800 odinDomain[57322:1491164] current thread = <NSThread: 0x600000464a80>{number = 5, name = (null)}, index = 4
2019-08-30 16:34:40.001950+0800 odinDomain[57322:1491164] current thread = <NSThread: 0x600000464a80>{number = 5, name = (null)}, index = 5
2019-08-30 16:34:40.002119+0800 odinDomain[57322:1491164] current thread = <NSThread: 0x600000464a80>{number = 5, name = (null)}, index = 6
2019-08-30 16:34:40.002254+0800 odinDomain[57322:1491164] current thread = <NSThread: 0x600000464a80>{number = 5, name = (null)}, index = 7
2019-08-30 16:34:40.002762+0800 odinDomain[57322:1491164] current thread = <NSThread: 0x600000464a80>{number = 5, name = (null)}, index = 8
2019-08-30 16:34:40.002905+0800 odinDomain[57322:1491164] current thread = <NSThread: 0x600000464a80>{number = 5, name = (null)}, index = 9

代码是在主线程执行的,从日志可以看出,串行队列异步执行任务,会新建一个线程,然后串行队列的任务会在新建的线程里面,按照加入的顺序执行,这与我们预期的效果是一样的。

现在将代码改动 如下

    dispatch_queue_t q = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
    
    for (NSUInteger i = 0; i < 10; i++) {
        NSLog(@"start request index = %@", @(i));
        [ODMHttp post:@"http://192.168.124.11:5000/odindomain" parameters:@{@"index": @(i)} success:^(id  _Nullable responseObject) {
            NSLog(@"callback thread = %@, index = %@", NSThread.currentThread, @(i));
            dispatch_async(q, ^{
                NSLog(@"async thread = %@, index = %@", NSThread.currentThread, @(i));
            });
        } failure:^(NSError * _Nullable error) {}];
    }

打印的日志如下:

17:14:37.7034 callback thread = <NSThread: 0x600000279880>{number = 4, name = (null)}, index = 1
17:14:37.7046 async thread = <NSThread: 0x600000279880>{number = 4, name = (null)}, index = 1
17:14:37.7108 callback thread = <NSThread: 0x60000027cf00>{number = 5, name = (null)}, index = 2
17:14:37.7116 callback thread = <NSThread: 0x60000027cf00>{number = 5, name = (null)}, index = 0
17:14:37.7117 async thread = <NSThread: 0x600000279880>{number = 4, name = (null)}, index = 2
17:14:37.7127 callback thread = <NSThread: 0x60000027cf00>{number = 5, name = (null)}, index = 3
17:14:37.7128 async thread = <NSThread: 0x600000279880>{number = 4, name = (null)}, index = 0
17:14:37.7138 async thread = <NSThread: 0x600000279880>{number = 4, name = (null)}, index = 3
17:14:37.7457 callback thread = <NSThread: 0x604000460380>{number = 6, name = (null)}, index = 4
17:14:37.7461 async thread = <NSThread: 0x604000460380>{number = 6, name = (null)}, index = 4
17:14:37.7672 callback thread = <NSThread: 0x60000027cf00>{number = 5, name = (null)}, index = 5
17:14:37.7686 callback thread = <NSThread: 0x60000027cf00>{number = 5, name = (null)}, index = 6
17:14:37.7694 async thread = <NSThread: 0x600000279880>{number = 4, name = (null)}, index = 5
17:14:37.7745 async thread = <NSThread: 0x600000279880>{number = 4, name = (null)}, index = 6
17:14:37.7839 callback thread = <NSThread: 0x600000279880>{number = 4, name = (null)}, index = 7
17:14:37.7853 async thread = <NSThread: 0x60000027c300>{number = 7, name = (null)}, index = 7
17:14:37.7928 callback thread = <NSThread: 0x600000279880>{number = 4, name = (null)}, index = 8
17:14:37.7945 async thread = <NSThread: 0x604000460380>{number = 6, name = (null)}, index = 8
17:14:37.7960 callback thread = <NSThread: 0x60000027d8c0>{number = 8, name = (null)}, index = 9
17:14:37.7968 async thread = <NSThread: 0x60000027d8c0>{number = 8, name = (null)}, index = 9

由此可以发现问题,将任务添加到串行队列之后,串行队列在执行任务的时候,并不是在一个线程,从而引发另一个问题,这些任务的执行有两种情况,并发和串行。
因为是任务在不同的线程执行的,所以怀疑可能是并发的执行;
又因为是在串行队列中,所以也可能是串行执行,只不过是自不同线程的里面的执行的。
于是将代码改为如下所示:

@interface ViewController ()

@property (nonatomic, assign) NSInteger counts;

@end

- (void)viewDidLoad {
    [super viewDidLoad];
    self.counts = 1000;
}

- (void)testRequestQueue {
    dispatch_queue_t q = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
    
    for (NSUInteger i = 0; i < 100; i++) {
        NSLog(@"start request index = %@", @(i));
        [ODMHttp post:@"http://192.168.124.11:5000/odindomain" parameters:@{@"index": @(i)} success:^(id  _Nullable responseObject) {
            NSLog(@"callback thread = %@, index = %@", NSThread.currentThread, @(i));
            dispatch_async(q, ^{
                self.counts -= 1;
                NSLog(@"async thread = %@, index = %@ counts = %@", NSThread.currentThread, @(i), @(self.counts));
            });
        } failure:^(NSError * _Nullable error) {
            
        }];
    }
}

如果是多线程并发执行任务的话,那么counts打印的顺序应该会是乱序,经过我多次测试,counts的打印都是顺序的。

再者如果在打印count之前再添加一句代码

[NSThread sleepForTimeInterval:3];

那么会发现结果很有意思,所有的任务的执行又放在同一个线程里面,并且是串行执行的。

由以上的测试的结果,可以得出一个粗略的结论,串行队列可以保证队列里的任务是串行执行的,但是不能保证这些任务是在同一个线程里面执行 。这里面涉及到iOS对线程复用的知识,还未深究。

相关文章

  • Lan的ScalersTalk第四轮新概念朗读持续力训练Day

    练习材料: [Day 1799 2019-08-30] Lesson 37-4 The process of ag...

  • 2019-08-30看足球:欧罗巴杯 01:15 莫斯科斯巴达

    2019-08-30 欧罗巴杯 01:15 莫斯科斯巴达 VS 布拉加 主队信息: 在首回合交手莫斯科斯巴达以0-...

  • 用心去感受“孤独”

    拥有了孤独的人,才能拥有真正的自我。 2019-08-30 学习实验第30天打卡 最终目标:操着一口流利的英语,拥...

  • 2019-08-31间歇跑5

    时间:2019-08-30 线路:绿道 成绩:间歇跑800米*6用时59分 感受:今天是8月最后一次跑步,全月共跑...

  • 觉察带来真正的改变

    化蛹2019-08-30 来自专辑 个人成长 你有没有感叹过:心灵成长的道路好艰辛啊!参加了好多课程,花费了时间、...

  • 初识龙里·感谢生命里的不期而遇

    2019-08-30 星期五 晨雨 八月偶遇了一本《播种人的手绘人生》,作者将自己农耕与手工缝制的生活用绘...

  • 掌控命运

    毒贩与牧师 时间: 2019-08-30 作者:执笔言情 一个毒贩被警察追捕甚紧,逃躲到一间教堂里。 他盘算着警方...

  • 2019-08-30

    第二天早上,林蓁便来到哥哥家,当她打开门时,那一瞬间,她闻到了淡淡的烟草味,混合着冷冽的男性气息。 只看见,一...

  • 2019-08-30

    第二天早上,林蓁便来到哥哥家,当她打开门时,那一瞬间,她闻到了淡淡的烟草味,混合着冷冽的男性气息。 只看见,一...

  • 2019-08-30

    我不知道,世间的正确,亦不明白世间的错误。因为在每一时刻你都被有相对的理由。除非你在正确的极端,或者错误的极端。 ...

网友评论

      本文标题:2019-08-30

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