混合同步/asynchronous与串行/并发队列时,调度程序如何工作?

在Grand Central Dispatch中,在使用dispatch_sync函数和dispatch_async函数时, dispatch_sync如何使用不同的队列( serialconcurrent )?

首先,我们需要两种types的队列 :一个串行和一个并发

 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] block 1 added

2014-04-08 14:43:16.468 dispex [4346:60b] block 2 added

2014-04-08 14:43:16.468 dispex [4346:1303] block 1

2014-04-08 14:43:16.469 dispex [4346:1303] block 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] block 4 added

2014-04-08 14:43:16.469 dispex [4346:1303]块4

2014-04-08 14:43:16.469 dispex [4346:60b] block 5 added

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] block 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] block 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]所有块已添加到排队 – >function已返回

正如你所看到的,块被添加到队列中,但同时调度器开始执行它们 。 这是dispatcher_async函数的一个特性,即将队列添加到队列中,而不用等待它们完成执行 。 换句话说,如果你在函数中使用dispatch_async ,函数立即返回,同时块正在执行。 这非常有用! 在这个例子中,我使用NSLog报告块何时被添加到队列中,所以这确实是执行较慢,并导致日志

全部join

最后。 但正如我们将要看到的那样,没有日志,它会在开始时写下来。 由于我们正在使用一个串行队列,所以这个块按照添加的顺序执行。

下一个:

 /* 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:同步 – 队列:串行

2014-04-08 14:43:16.473 dispex [4346:60b] block 1 added

2014-04-08 14:43:16.474 dispex [4346:60b] block 1

2014-04-08 14:43:16.474 dispex [4346:60b] block 2 added

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] block 5

2014-04-08 14:43:16.476 dispex [4346:60b] block 6 added

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]块8添加

第四部分:第四部分:第四部分:第四部分:第四部分

2014-04-08 14:43:16.478 dispex [4346:60b]块9添加

第9部分2014年4月8日14:43:16.478 dispex [4346:60b]

2014-04-08 14:43:16.479 dispex [4346:60b]添加了块10

2014-04-08 14:43:16.479 dispex [4346:60b] block 10

2014-04-08 14:43:16.479 dispex [4346:60b]所有块已添加到队列 – >function已退回

在这个例子中,我们使用dispatch_sync函数和一个串行队列 。 很容易看到,当前面的块完成执行时,所有块都被添加。 这是dispatch_sync一个特性。 换句话说,该function在块执行完成之前不会返回。 由于这是一个串行队列的事实,这里的顺序也是受到尊重的。

下一个:

 /* 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:并发

2014-04-08 14:43:16.480 dispex [4346:60b]所有块已添加到队列 – >function已返回

2014-04-08 14:43:16.480 dispex [4346:1303] block 1

2014-04-08 14:43:16.480 dispex [4346:3503] block 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] block 4

2014-04-08 14:43:16.480 dispex [4346:3903] block 6

2014-04-08 14:43:16.480 dispex [4346:3a03] block 7

2014-04-08 14:43:16.480 dispex [4346:3b03] block 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] block 12

2014-04-08 14:43:16.483 dispex [4346:3703]块13

2014-04-08 14:43:16.483 dispex [4346:3903] block 14

2014-04-08 14:43:16.483 dispex [4346:3603] block 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:同步 – 队列:并行

2014-04-08 14:43:16.486 dispex [4346:60b] block 1 added

2014-04-08 14:43:16.486 dispex [4346:60b] block 1

2014-04-08 14:43:16.487 dispex [4346:60b] block 2 added

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] block 5

2014-04-08 14:43:16.489 dispex [4346:60b] block 6 added

2014-04-08 14:43:16.489 dispex [4346:60b] block 6

2014-04-08 14:43:16.490 dispex [4346:60b]块7添加

方块7:2014-04-08 14:43:16.490 dispex [4346:60b]

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] block 9

2014-04-08 14:43:16.492 dispex [4346:60b]块10添加

2014-04-08 14:43:16.492 dispex [4346:60b] block 10

2014-04-08 14:43:16.492 dispex [4346:60b]所有块已添加到队列 – >function已返回

最后,在这里我们使用dispatch_sync并发队列 。 这似乎完全等于情侣同步/序列。 在这种情况下是这样的。 这是因为,如果队列是并发的,它没有其他的块执行,因为我们使用同步调度器,所以它等待添加下一个块,直到实际没有完成执行。 这种types的对( 同步/并发 )是有用的,如果我们也添加到队列, dispatch_async块。 在这种情况下,调度员可以将其他块添加到队列中执行。

希望这个迷你示范有用;)

干杯!