在Grand Central Dispatch中,当使用serial
函数和concurrent
函数时,调度程序如何使用不同的队列(dispatch_sync
和dispatch_async
)?
答案 0 :(得分:3)
首先,我们需要两种队列:一种序列和一种并发:
dispatch_queue_t serialQueue =
dispatch_queue_create("com.matteogobbi.dispex.serial_queue", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t concurrentQueue =
dispatch_queue_create("com.matteogobbi.dispex.concurrent_queue", DISPATCH_QUEUE_CONCURRENT);
因此,我们可以从第一个实验开始,使用串行队列和所有dispatch_async
函数将我们的块添加到队列中:
/* Dispatch async with serial queue */
NSLog(@"\n\nDISPATCH: Async - QUEUE: Serial");
NSLog(@"block 1 added");
dispatch_async(serialQueue, ^{
NSLog(@"block 1");
});
NSLog(@"block 2 added");
dispatch_async(serialQueue, ^{
NSLog(@"block 2");
});
NSLog(@"block 3 added");
dispatch_async(serialQueue, ^{
NSLog(@"block 3");
});
NSLog(@"block 4 added");
dispatch_async(serialQueue, ^{
NSLog(@"block 4");
});
NSLog(@"block 5 added");
dispatch_async(serialQueue, ^{
NSLog(@"block 5");
});
NSLog(@"block 6 added");
dispatch_async(serialQueue, ^{
NSLog(@"block 6");
});
NSLog(@"block 7 added");
dispatch_async(serialQueue, ^{
NSLog(@"block 7");
});
NSLog(@"block 8 added");
dispatch_async(serialQueue, ^{
NSLog(@"block 8");
});
NSLog(@"block 9 added");
dispatch_async(serialQueue, ^{
NSLog(@"block 9");
});
NSLog(@"block 10 added");
dispatch_async(serialQueue, ^{
NSLog(@"block 10");
});
NSLog(@"ALL BLOCK ADDED TO THE QUEUE --> FUNCTION RETURNED");
DISPATCH:Async - QUEUE:Serial
2014-04-08 14:43:16.468 dispex [4346:60b]第1块补充
2014-04-08 14:43:16.468 dispex [4346:60b]第2块补充
2014-04-08 14:43:16.468 dispex [4346:1303]第1块
2014-04-08 14:43:16.469 dispex [4346:1303]第2块
2014-04-08 14:43:16.468 dispex [4346:60b]第3块补充
2014-04-08 14:43:16.469 dispex [4346:1303]第3块
2014-04-08 14:43:16.469 dispex [4346:60b]第4块补充
2014-04-08 14:43:16.469 dispex [4346:1303] block 4
2014-04-08 14:43:16.469 dispex [4346:60b]第5块补充
2014-04-08 14:43:16.470 dispex [4346:60b]第6块补充
2014-04-08 14:43:16.470 dispex [4346:1303]第5块
2014-04-08 14:43:16.471 dispex [4346:60b]第7块补充
2014-04-08 14:43:16.471 dispex [4346:1303]第6块
2014-04-08 14:43:16.471 dispex [4346:1303]第7块
2014-04-08 14:43:16.471 dispex [4346:60b]第8块补充
2014-04-08 14:43:16.471 dispex [4346:1303]第8块
2014-04-08 14:43:16.471 dispex [4346:60b]第9块补充
2014-04-08 14:43:16.472 dispex [4346:60b]第10块补充
2014-04-08 14:43:16.472 dispex [4346:1303]第9块
2014-04-08 14:43:16.472 dispex [4346:1303]第10块
2014-04-08 14:43:16.472 dispex [4346:60b]所有积木都加入了队列 - >功能返回
如您所见,该块已添加到队列中,但同时调度程序开始执行它们。这是dispatcher_async
函数的一个特征,即将队列添加到队列而不等待它们完成执行。换句话说,如果在函数中使用dispatch_async
,函数会立即返回,同时块正在执行。这非常有用!在这个例子中,我使用NSLog来报告何时将块添加到队列中,因此执行速度较慢并导致日志
所有已添加的块
最后。但正如我们将要看到的那样,没有日志,它将在开头写入。由于我们使用的是串行队列,因此按照添加顺序执行块。
下一步:
/* Just wait before begin with the next test */
dispatch_group_wait(group_async_serial, DISPATCH_TIME_FOREVER);
/* Dispatch sync with serial queue */
NSLog(@"\n\nDISPATCH: Sync - QUEUE: Serial");
NSLog(@"block 1 added");
dispatch_sync(serialQueue, ^{
NSLog(@"block 1");
});
NSLog(@"block 2 added");
dispatch_sync(serialQueue, ^{
NSLog(@"block 2");
});
NSLog(@"block 3 added");
dispatch_sync(serialQueue, ^{
NSLog(@"block 3");
});
NSLog(@"block 4 added");
dispatch_sync(serialQueue, ^{
NSLog(@"block 4");
});
NSLog(@"block 5 added");
dispatch_sync(serialQueue, ^{
NSLog(@"block 5");
});
NSLog(@"block 6 added");
dispatch_sync(serialQueue, ^{
NSLog(@"block 6");
});
NSLog(@"block 7 added");
dispatch_sync(serialQueue, ^{
NSLog(@"block 7");
});
NSLog(@"block 8 added");
dispatch_sync(serialQueue, ^{
NSLog(@"block 8");
});
NSLog(@"block 9 added");
dispatch_sync(serialQueue, ^{
NSLog(@"block 9");
});
NSLog(@"block 10 added");
dispatch_sync(serialQueue, ^{
NSLog(@"block 10");
});
NSLog(@"ALL BLOCK ADDED TO THE QUEUE --> FUNCTION RETURNED");
DISPATCH:Sync - QUEUE:Serial
2014-04-08 14:43:16.473 dispex [4346:60b]第1块补充
2014-04-08 14:43:16.474 dispex [4346:60b] block 1
2014-04-08 14:43:16.474 dispex [4346:60b]第2块补充
2014-04-08 14:43:16.474 dispex [4346:60b] block 2
2014-04-08 14:43:16.475 dispex [4346:60b]第3块补充
2014-04-08 14:43:16.475 dispex [4346:60b] block 3
2014-04-08 14:43:16.475 dispex [4346:60b]第4块补充
2014-04-08 14:43:16.475 dispex [4346:60b] block 4
2014-04-08 14:43:16.476 dispex [4346:60b]第5块补充
2014-04-08 14:43:16.476 dispex [4346:60b]第5块
2014-04-08 14:43:16.476 dispex [4346:60b]第6块补充
2014-04-08 14:43:16.477 dispex [4346:60b] block 6
2014-04-08 14:43:16.477 dispex [4346:60b]第7块补充
2014-04-08 14:43:16.477 dispex [4346:60b]第7块
2014-04-08 14:43:16.477 dispex [4346:60b]第8块补充
2014-04-08 14:43:16.478 dispex [4346:60b] block 8
2014-04-08 14:43:16.478 dispex [4346:60b]第9块补充
2014-04-08 14:43:16.478 dispex [4346:60b]第9块
2014-04-08 14:43:16.479 dispex [4346:60b]第10块补充
2014-04-08 14:43:16.479 dispex [4346:60b]第10块
2014-04-08 14:43:16.479 dispex [4346:60b]所有积木都加入了队列 - >功能返回
在此示例中,我们使用dispatch_sync
函数和串行队列。很容易看出,当前一个块完成执行时,所有块都被添加。这是dispatch_sync
的特征。换句话说,函数不会返回,直到执行块结束。由于这是一个串行队列,因此这里的顺序也得到了尊重。
下一步:
/* Dispatch async with concurrent queue */
NSLog(@"\n\nDISPATCH: Async - QUEUE: Concurrent");
dispatch_group_t group_async_concurrent = dispatch_group_create();
dispatch_group_async(group_async_concurrent, concurrentQueue, ^{
NSLog(@"block 1");
});
dispatch_group_async(group_async_concurrent, concurrentQueue, ^{
NSLog(@"block 2");
});
dispatch_group_async(group_async_concurrent, concurrentQueue, ^{
NSLog(@"block 3");
});
dispatch_group_async(group_async_concurrent, concurrentQueue, ^{
NSLog(@"block 4");
});
dispatch_group_async(group_async_concurrent, concurrentQueue, ^{
NSLog(@"block 5");
});
dispatch_group_async(group_async_concurrent, concurrentQueue, ^{
NSLog(@"block 6");
});
dispatch_group_async(group_async_concurrent, concurrentQueue, ^{
NSLog(@"block 7");
});
dispatch_group_async(group_async_concurrent, concurrentQueue, ^{
NSLog(@"block 8");
});
dispatch_group_async(group_async_concurrent, concurrentQueue, ^{
NSLog(@"block 9");
});
dispatch_group_async(group_async_concurrent, concurrentQueue, ^{
NSLog(@"block 10");
});
dispatch_group_async(group_async_concurrent, concurrentQueue, ^{
NSLog(@"block 11");
});
dispatch_group_async(group_async_concurrent, concurrentQueue, ^{
NSLog(@"block 12");
});
dispatch_group_async(group_async_concurrent, concurrentQueue, ^{
NSLog(@"block 13");
});
dispatch_group_async(group_async_concurrent, concurrentQueue, ^{
NSLog(@"block 14");
});
NSLog(@"ALL BLOCK ADDED TO THE QUEUE --> FUNCTION RETURNED");
DISPATCH:Async - QUEUE:Concurrent
2014-04-08 14:43:16.480 dispex [4346:60b]所有积木都加入了队列 - >功能返回
2014-04-08 14:43:16.480 dispex [4346:1303]第1块
2014-04-08 14:43:16.480 dispex [4346:3503]第2块
2014-04-08 14:43:16.480 dispex [4346:3603]第3块
2014-04-08 14:43:16.480 dispex [4346:3803]第5块
2014-04-08 14:43:16.480 dispex [4346:3703]第4块
2014-04-08 14:43:16.480 dispex [4346:3903]第6块
2014-04-08 14:43:16.480 dispex [4346:3a03]第7块
2014-04-08 14:43:16.480 dispex [4346:3b03]第8块
2014-04-08 14:43:16.482 dispex [4346:1303]第9块
2014-04-08 14:43:16.483 dispex [4346:3503]第10块
2014-04-08 14:43:16.483 dispex [4346:3803]第12块
2014-04-08 14:43:16.483 dispex [4346:3703]第13块
2014-04-08 14:43:16.483 dispex [4346:3903]第14块
2014-04-08 14:43:16.483 dispex [4346:3603]第11块
正如我之前所说的,这里我展示了如何工作dispatch_async
但是并发队列。
这非常有趣,因为如果没有NSLog显示何时添加块,您可以看到在执行第一个块之前如何添加所有块。此行为不是常量。 可能会执行block1并在dispatch_async
完成后立即将所有块添加到队列中,然后继续执行其他块。另外需要注意的是,块是同时执行的,因此它们并不尊重添加的顺序,而且这种行为不是恒定的,而是取决于CPU的使用,性能和许多其他因素。
下一步:
/* Just wait before begin with the next test */
dispatch_group_wait(group_async_concurrent, DISPATCH_TIME_FOREVER);
/* Dispatch sync with concurrent queue */
NSLog(@"\n\nDISPATCH: Sync - QUEUE: Concurrent");
NSLog(@"block 1 added");
dispatch_sync(concurrentQueue, ^{
NSLog(@"block 1");
});
NSLog(@"block 2 added");
dispatch_sync(concurrentQueue, ^{
NSLog(@"block 2");
});
NSLog(@"block 3 added");
dispatch_sync(concurrentQueue, ^{
NSLog(@"block 3");
});
NSLog(@"block 4 added");
dispatch_sync(concurrentQueue, ^{
NSLog(@"block 4");
});
NSLog(@"block 5 added");
dispatch_sync(concurrentQueue, ^{
NSLog(@"block 5");
});
NSLog(@"block 6 added");
dispatch_sync(concurrentQueue, ^{
NSLog(@"block 6");
});
NSLog(@"block 7 added");
dispatch_sync(concurrentQueue, ^{
NSLog(@"block 7");
});
NSLog(@"block 8 added");
dispatch_sync(concurrentQueue, ^{
NSLog(@"block 8");
});
NSLog(@"block 9 added");
dispatch_sync(concurrentQueue, ^{
NSLog(@"block 9");
});
NSLog(@"block 10 added");
dispatch_sync(concurrentQueue, ^{
NSLog(@"block 10");
});
NSLog(@"ALL BLOCK ADDED TO THE QUEUE --> FUNCTION RETURNED");
DISPATCH:Sync - QUEUE:Concurrent
2014-04-08 14:43:16.486 dispex [4346:60b]第1块补充
2014-04-08 14:43:16.486 dispex [4346:60b] block 1
2014-04-08 14:43:16.487 dispex [4346:60b]第2块补充
2014-04-08 14:43:16.487 dispex [4346:60b] block 2
2014-04-08 14:43:16.487 dispex [4346:60b]第3块补充
2014-04-08 14:43:16.488 dispex [4346:60b] block 3
2014-04-08 14:43:16.488 dispex [4346:60b]第4块补充
2014-04-08 14:43:16.488 dispex [4346:60b] block 4
2014-04-08 14:43:16.489 dispex [4346:60b]第5块补充
2014-04-08 14:43:16.489 dispex [4346:60b]第5块
2014-04-08 14:43:16.489 dispex [4346:60b]第6块补充
2014-04-08 14:43:16.489 dispex [4346:60b] block 6
2014-04-08 14:43:16.490 dispex [4346:60b]第7块补充
2014-04-08 14:43:16.490 dispex [4346:60b]第7块
2014-04-08 14:43:16.490 dispex [4346:60b]第8块补充
2014-04-08 14:43:16.491 dispex [4346:60b] block 8
2014-04-08 14:43:16.491 dispex [4346:60b]第9块补充
2014-04-08 14:43:16.491 dispex [4346:60b]第9块
2014-04-08 14:43:16.492 dispex [4346:60b]第10块补充
2014-04-08 14:43:16.492 dispex [4346:60b]第10块
2014-04-08 14:43:16.492 dispex [4346:60b]所有积木都加入了队列 - >功能返回
最后,我们将dispatch_sync
与并发队列一起使用。它似乎完全等同于夫妻同步/串行。在这种情况下是如此。这种行为的原因在于,如果队列是并发的,它还没有其他块执行,因为我们正在使用同步调度程序,所以它等待添加下一个块,直到实际没有完成要执行。如果我们还要添加dispatch_async
的块,那么这种类型的对( sync / concurrent )非常有用。在这种情况下,调度程序可以将其他块添加到要执行的队列中。
希望这个迷你演示有用;)
干杯!