为什么异步并行队列最后运行

时间:2018-03-22 11:33:21

标签: ios objective-c multithreading queue grand-central-dispatch

我认为"结束"将打印for循环,但这是错误的,你能告诉我为什么。这是代码:

dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);

for (NSUInteger i = 0; i < 1000; i++) {
    dispatch_async(queue, ^{
        NSLog(@"i:%lu", (unsigned long)i);
    });
}

dispatch_async(queue, ^{
    NSLog(@"end:%@", [NSThread currentThread]);
});

结果:

2018-03-22 19:26:33.812371+0800 MyIOSNote[96704:912772] i:990
2018-03-22 19:26:33.812671+0800 MyIOSNote[96704:912801] i:991
2018-03-22 19:26:33.812935+0800 MyIOSNote[96704:912662] i:992
2018-03-22 19:26:33.813295+0800 MyIOSNote[96704:912802] i:993
2018-03-22 19:26:33.813552+0800 MyIOSNote[96704:912766] i:994
2018-03-22 19:26:33.813856+0800 MyIOSNote[96704:912778] i:995
2018-03-22 19:26:33.814299+0800 MyIOSNote[96704:912803] i:996
2018-03-22 19:26:33.814648+0800 MyIOSNote[96704:912779] i:997
2018-03-22 19:26:33.814930+0800 MyIOSNote[96704:912759] i:998
2018-03-22 19:26:33.815361+0800 MyIOSNote[96704:912804] i:999
2018-03-22 19:26:33.815799+0800 MyIOSNote[96704:912805] end:<NSThread:             0x60400027e200>{number = 3, name = (null)}

3 个答案:

答案 0 :(得分:1)

查看执行顺序。您首先将1000个块排入队列以打印数字。然后你将块排队打印&#34;结束&#34;。所有这些块都被排队以在同一并发后台队列上异步运行。对dispatch_async的所有1001次调用按顺序完成,一次一个,在运行此代码的任何线程上,来自不同队列的所有排队块都将运行。

并发队列将按照排队的顺序弹出每个块并运行它。由于它是一个并发队列,并且由于每个都是异步运行的,理论上它们中的一些可能有点乱序。但总的来说,输出将以相同的顺序出现,因为每个块完全相同 - 一个简单的NSLog语句。

但简短的回答是&#34;结束&#34;最后打印,因为它在排队所有其他区块之后最后排队。

可能有帮助的是记录每个呼叫的入口:

dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);

for (NSUInteger i = 0; i < 1000; i++) {
    NSLog(@"enqueue i: %lu", (unsigned long)i);
    dispatch_async(queue, ^{
        NSLog(@"run i: %lu", (unsigned long)i);
    });
}

NSLog(@"enqueue end");
dispatch_async(queue, ^{
    NSLog(@"run end: %@", [NSThread currentThread]);
});

答案 1 :(得分:0)

对于循环代码在主队列(Serial)中运行,因此for循环结束然后打印结束语句,如果你将for循环包装在异步内部,就像这样

dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
   dispatch_async(queue, ^{

     for (NSUInteger i = 0; i < 1000; i++) {

         NSLog(@"i:%lu", (unsigned long)i);

     }
 });
dispatch_async(queue, ^{
    NSLog(@"end:%@", [NSThread currentThread]);
});
你会得到这个 enter image description here

答案 2 :(得分:0)

要结合以前的两个答案,最后打印end的原因是因为您按顺序排队,但每个块执行得非常快。当您将end的日志排入队列时,所有其他块都已执行。