如何混合调度工作时同步/异步串行/并行队列? [英] How does the dispatcher work when mixing sync/async with serial/concurrent queue?

查看:120
本文介绍了如何混合调度工作时同步/异步串行/并行队列?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在大中央调度,如何与不同的队列调度工作(串口并行)使用时, dispatch_sync 函数和 dispatch_async 功能?


解决方案

首先我们需要两个类型的队列:一种串口和一个并行

  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 功能给我们的模块添加到队列:

  / *调度异步串行队列* /
的NSLog(@\\ n \\ nDISPATCH:异步 - 队列:串行);的NSLog(@块加1);
dispatch_async(serialQueue,^ {
    的NSLog(@块1);
});的NSLog(@块2加);
dispatch_async(serialQueue,^ {
    的NSLog(@块2);
});的NSLog(@块3中添加);
dispatch_async(serialQueue,^ {
    的NSLog(@块3);
});的NSLog(@块4加);
dispatch_async(serialQueue,^ {
    的NSLog(@块4);
});的NSLog(@块5中添加);
dispatch_async(serialQueue,^ {
    的NSLog(@块5);
});的NSLog(@块6增加了);
dispatch_async(serialQueue,^ {
    的NSLog(@块6);
});的NSLog(@块7中添加);
dispatch_async(serialQueue,^ {
    的NSLog(@块7);
});的NSLog(@块8加);
dispatch_async(serialQueue,^ {
    的NSLog(@块8);
});的NSLog(@块9加);
dispatch_async(serialQueue,^ {
    的NSLog(@块9);
});的NSLog(@块10加);
dispatch_async(serialQueue,^ {
    的NSLog(@块10);
});的NSLog(@所有的块加入到队列 - >函数返回);


  

调度:异步 - 队列:串行


  
  

2014年4月8日14:43:16.468 DISPEX [4346:60B]阻止加1


  
  

2014年4月8日14:43:16.468 DISPEX [4346:60B]块2添加


  
  

2014年4月8日14:43:16.468 DISPEX [4346:1303]块1


  
  

2014年4月8日14:43:16.469 DISPEX [4346:1303]块2


  
  

2014年4月8日14:43:16.468 DISPEX [4346:60B]块3添加


  
  

2014年4月8日14:43:16.469 DISPEX [4346:1303]块3


  
  

2014年4月8日14:43:16.469 DISPEX [4346:60B]块4,添加


  
  

2014年4月8日14:43:16.469 DISPEX [4346:1303] 4块


  
  

2014年4月8日14:43:16.469 DISPEX [4346:60B]块5中添加


  
  

2014年4月8日14:43:16.470 DISPEX [4346:60B] 6块添加


  
  

2014年4月8日14:43:16.470 DISPEX [4346:1303] 5块


  
  

2014年4月8日14:43:16.471 DISPEX [4346:60B] 7座新增


  
  

2014年4月8日14:43:16.471 DISPEX [4346:1303] 6块


  
  

2014年4月8日14:43:16.471 DISPEX [4346:1303] 7座


  
  

2014年4月8日14:43:16.471 DISPEX [4346:60B]块8添加


  
  

2014年4月8日14:43:16.471 DISPEX [4346:1303] 8座


  
  

2014年4月8日14:43:16.471 DISPEX [4346:60B]块9添加


  
  

2014年4月8日14:43:16.472 DISPEX [4346:60B] 10座新增


  
  

2014年4月8日14:43:16.472 DISPEX [4346:1303] 9座


  
  

2014年4月8日14:43:16.472 DISPEX [4346:1303]第10座


  
  

2014年4月8日14:43:16.472 DISPEX [4346:60B]所有的块加入到队列
   - >函数返回


正如你可以看到,该块被添加到在此期间的队列中,但调度员开始执行它们。这是 dispatcher_async 函数的特点,那就是添加块队列中等待不认为他们完成被执行。换句话说,如果你使用 dispatch_async 在函数,该函数立即返回,并在此期间,该块被执行。这是非常有用的!在这个例子中我使用的NSLog报告当块被添加到队列,因此这样做是执行慢,导致日志


  

所有块中追加


末。但是,正如我们将看到后,没有记录它会在开头写道。由于我们使用的是串行队列的事实,该块在添加的顺序执行。

下一页:

  / *只是等待之前,下一个测试*开始/
dispatch_group_wait(group_async_serial,DISPATCH_TIME_FOREVER);
/ *调度同步串行队列* /
的NSLog(@\\ n \\ nDISPATCH:同步 - 队列:串行);的NSLog(@块加1);
dispatch_sync(serialQueue,^ {
    的NSLog(@块1);
});的NSLog(@块2加);
dispatch_sync(serialQueue,^ {
    的NSLog(@块2);
});的NSLog(@块3中添加);
dispatch_sync(serialQueue,^ {
    的NSLog(@块3);
});的NSLog(@块4加);
dispatch_sync(serialQueue,^ {
    的NSLog(@块4);
});的NSLog(@块5中添加);
dispatch_sync(serialQueue,^ {
    的NSLog(@块5);
});的NSLog(@块6增加了);
dispatch_sync(serialQueue,^ {
    的NSLog(@块6);
});的NSLog(@块7中添加);
dispatch_sync(serialQueue,^ {
    的NSLog(@块7);
});的NSLog(@块8加);
dispatch_sync(serialQueue,^ {
    的NSLog(@块8);
});的NSLog(@块9加);
dispatch_sync(serialQueue,^ {
    的NSLog(@块9);
});的NSLog(@块10加);
dispatch_sync(serialQueue,^ {
    的NSLog(@块10);
});的NSLog(@所有的块加入到队列 - >函数返回);


  

调度:同步 - 队列:串行


  
  

2014年4月8日14:43:16.473 DISPEX [4346:60B]阻止加1


  
  

2014年4月8日14:43:16.474 DISPEX [4346:60B]块1


  
  

2014年4月8日14:43:16.474 DISPEX [4346:60B]块2添加


  
  

2014年4月8日14:43:16.474 DISPEX [4346:60B]块2


  
  

2014年4月8日14:43:16.475 DISPEX [4346:60B]块3添加


  
  

2014年4月8日14:43:16.475 DISPEX [4346:60B]块3


  
  

2014年4月8日14:43:16.475 DISPEX [4346:60B]块4,添加


  
  

2014年4月8日14:43:16.475 DISPEX [4346:60B]块4


  
  

2014年4月8日14:43:16.476 DISPEX [4346:60B]块5中添加


  
  

2014年4月8日14:43:16.476 DISPEX [4346:60B]块5


  
  

2014年4月8日14:43:16.476 DISPEX [4346:60B] 6块添加


  
  

2014年4月8日14:43:16.477 DISPEX [4346:60B]块6


  
  

2014年4月8日14:43:16.477 DISPEX [4346:60B] 7座新增


  
  

2014年4月8日14:43:16.477 DISPEX [4346:60B] 7座


  
  

2014年4月8日14:43:16.477 DISPEX [4346:60B]块8添加


  
  

2014年4月8日14:43:16.478 DISPEX [4346:60B]块8


  
  

2014年4月8日14:43:16.478 DISPEX [4346:60B]块9添加


  
  

2014年4月8日14:43:16.478 DISPEX [4346:60B]块9


  
  

2014年4月8日14:43:16.479 DISPEX [4346:60B] 10座新增


  
  

2014年4月8日14:43:16.479 DISPEX [4346:60B] 10座


  
  

2014年4月8日14:43:16.479 DISPEX [4346:60B]所有的块加入到队列
   - >函数返回


在这个例子中,我们使用 dispatch_sync 函数以串行队列即可。这是很容易看到,当要执行的previous块完成所有的块被添加。这是 dispatch_sync 的特征。换句话说,函数不返回,直到被执行的程序段完成。由于事实是串行的队列,也在这里秩序得到尊重。

下一页:

  / *调度异步与并发队列* /
的NSLog(@\\ n \\ nDISPATCH:异步 - 队列:并行);
dispatch_group_t group_async_concurrent = dispatch_group_create();dispatch_group_async(group_async_concurrent,concurrentQueue,^ {
    的NSLog(@块1);
});dispatch_group_async(group_async_concurrent,concurrentQueue,^ {
    的NSLog(@块2);
});dispatch_group_async(group_async_concurrent,concurrentQueue,^ {
    的NSLog(@块3);
});dispatch_group_async(group_async_concurrent,concurrentQueue,^ {
    的NSLog(@块4);
});dispatch_group_async(group_async_concurrent,concurrentQueue,^ {
    的NSLog(@块5);
});dispatch_group_async(group_async_concurrent,concurrentQueue,^ {
    的NSLog(@块6);
});dispatch_group_async(group_async_concurrent,concurrentQueue,^ {
    的NSLog(@块7);
});dispatch_group_async(group_async_concurrent,concurrentQueue,^ {
    的NSLog(@块8);
});dispatch_group_async(group_async_concurrent,concurrentQueue,^ {
    的NSLog(@块9);
});dispatch_group_async(group_async_concurrent,concurrentQueue,^ {
    的NSLog(@块10);
});dispatch_group_async(group_async_concurrent,concurrentQueue,^ {
    的NSLog(@块11);
});dispatch_group_async(group_async_concurrent,concurrentQueue,^ {
    的NSLog(@块12);
});dispatch_group_async(group_async_concurrent,concurrentQueue,^ {
    的NSLog(@块13);
});dispatch_group_async(group_async_concurrent,concurrentQueue,^ {
    的NSLog(@块14);
});的NSLog(@所有的块加入到队列 - >函数返回);


  

调度:异步 - 队列:并发


  
  

2014年4月8日14:43:16.480 DISPEX [4346:60B]所有的块加入到队列
   - >函数返回


  
  

2014年4月8日14:43:16.480 DISPEX [4346:1303]块1


  
  

2014年4月8日14:43:16.480 DISPEX [4346:3503]块2


  
  

2014年4月8日14:43:16.480 DISPEX [4346:3603]块3


  
  

2014年4月8日14:43:16.480 DISPEX [4346:3803] 5块


  
  

2014年4月8日14:43:16.480 DISPEX [4346:3703] 4块


  
  

2014年4月8日14:43:16.480 DISPEX [4346:3903] 6块


  
  

2014年4月8日14:43:16.480 DISPEX [4346:3a03] 7座


  
  

2014年4月8日14:43:16.480 DISPEX [4346:3B03]块8


  
  

2014年4月8日14:43:16.482 DISPEX [4346:1303] 9座


  
  

2014年4月8日14:43:16.483 DISPEX [4346:3503]第10座


  
  

2014年4月8日14:43:16.483 DISPEX [4346:3803]方框12


  
  

2014年4月8日14:43:16.483 DISPEX [4346:3703] 13块


  
  

2014年4月8日14:43:16.483 DISPEX [4346:3903]块14


  
  

2014年4月8日14:43:16.483 DISPEX [4346:3603] 11块


正如我以前说过,我在这里展示如何工作 dispatch_async 但有一个并发队列即可。
这真的很有趣,因为如果没有的NSLog显示当添加块,你可以看到所有块是如何第一个块被执行之前。这种行为的不恒定可能发生块1被执行, dispatch_async 完成后,立即对所有块添加到队列,然后继续执行其他块。另外要注意的是,该块并发执行,所以他们不尊重加入的顺序,也是该行为不是恒定的,而是从CPU使用率,性能和其他许多事情都取决于

下一页:

  / *只是等待之前,下一个测试*开始/
dispatch_group_wait(group_async_concurrent,DISPATCH_TIME_FOREVER);
/ *调度同步并发队列* /
的NSLog(@\\ n \\ nDISPATCH:同步 - 队列:并发);的NSLog(@块加1);
dispatch_sync(concurrentQueue,^ {
    的NSLog(@块1);
});的NSLog(@块2加);
dispatch_sync(concurrentQueue,^ {
    的NSLog(@块2);
});的NSLog(@块3中添加);
dispatch_sync(concurrentQueue,^ {
    的NSLog(@块3);
});的NSLog(@块4加);
dispatch_sync(concurrentQueue,^ {
    的NSLog(@块4);
});的NSLog(@块5中添加);
dispatch_sync(concurrentQueue,^ {
    的NSLog(@块5);
});的NSLog(@块6增加了);
dispatch_sync(concurrentQueue,^ {
    的NSLog(@块6);
});的NSLog(@块7中添加);
dispatch_sync(concurrentQueue,^ {
    的NSLog(@块7);
});的NSLog(@块8加);
dispatch_sync(concurrentQueue,^ {
    的NSLog(@块8);
});的NSLog(@块9加);
dispatch_sync(concurrentQueue,^ {
    的NSLog(@块9);
});的NSLog(@块10加);
dispatch_sync(concurrentQueue,^ {
    的NSLog(@块10);
});的NSLog(@所有的块加入到队列 - >函数返回);


  

调度:同步 - 队列:并发


  
  

2014年4月8日14:43:16.486 DISPEX [4346:60B]阻止加1


  
  

2014年4月8日14:43:16.486 DISPEX [4346:60B]块1


  
  

2014年4月8日14:43:16.487 DISPEX [4346:60B]块2添加


  
  

2014年4月8日14:43:16.487 DISPEX [4346:60B]块2


  
  

2014年4月8日14:43:16.487 DISPEX [4346:60B]块3添加


  
  

2014年4月8日14:43:16.488 DISPEX [4346:60B]块3


  
  

2014年4月8日14:43:16.488 DISPEX [4346:60B]块4,添加


  
  

2014年4月8日14:43:16.488 DISPEX [4346:60B]块4


  
  

2014年4月8日14:43:16.489 DISPEX [4346:60B]块5中添加


  
  

2014年4月8日14:43:16.489 DISPEX [4346:60B]块5


  
  

2014年4月8日14:43:16.489 DISPEX [4346:60B] 6块添加


  
  

2014年4月8日14:43:16.489 DISPEX [4346:60B]块6


  
  

2014年4月8日14:43:16.490 DISPEX [4346:60B] 7座新增


  
  

2014年4月8日14:43:16.490 DISPEX [4346:60B] 7座


  
  

2014年4月8日14:43:16.490 DISPEX [4346:60B]块8添加


  
  

2014年4月8日14:43:16.491 DISPEX [4346:60B]块8


  
  

2014年4月8日14:43:16.491 DISPEX [4346:60B]块9添加


  
  

2014年4月8日14:43:16.491 DISPEX [4346:60B]块9


  
  

2014年4月8日14:43:16.492 DISPEX [4346:60B] 10座新增


  
  

2014年4月8日14:43:16.492 DISPEX [4346:60B] 10座


  
  

2014年4月8日14:43:16.492 DISPEX [4346:60B]所有的块加入到队列
   - >函数返回


最后,在这里我们使用 dispatch_sync 并发队列即可。它似乎完全等于夫妻俩同步/串口。在这种情况下是如此。此行为是由于还如果队列是并发的,它没有得到其他的块来执行,因为我们使用的同步调度,因此,它等待下一个块添加到实际没有完成要执行的事实。这种类型的夫妇(同步/并行)是有用的,如果我们也加入到队列,用 dispatch_async 块。在这种情况下,调度器可以具有其它的块添加到要执行的队列。

希望这个小演示一直有用)

干杯!

In Grand Central Dispatch, how does the dispatcher work with different queues (serial and concurrent) when using the dispatch_sync function and the dispatch_async function?

解决方案

First of all we need two type of queue: one serial and one concurrent:

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);

So, we can start with the first experiment, using a serial queue and all dispatch_async function to add our block to the queue:

/* 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] block 3 added

2014-04-08 14:43:16.469 dispex[4346:1303] block 3

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

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

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

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

2014-04-08 14:43:16.470 dispex[4346:1303] block 5

2014-04-08 14:43:16.471 dispex[4346:60b] block 7 added

2014-04-08 14:43:16.471 dispex[4346:1303] block 6

2014-04-08 14:43:16.471 dispex[4346:1303] block 7

2014-04-08 14:43:16.471 dispex[4346:60b] block 8 added

2014-04-08 14:43:16.471 dispex[4346:1303] block 8

2014-04-08 14:43:16.471 dispex[4346:60b] block 9 added

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

2014-04-08 14:43:16.472 dispex[4346:1303] block 9

2014-04-08 14:43:16.472 dispex[4346:1303] block 10

2014-04-08 14:43:16.472 dispex[4346:60b] ALL BLOCK ADDED TO THE QUEUE --> FUNCTION RETURNED

As you can see, the block are added to the queue but in the meantime the dispatcher begin to execute them. This is a characteristic of the dispatcher_async function, that is add block to the queue without wait that them finish to be executed. In other words, if you are using dispatch_async in a function, the function return immediately and in the meantime the block is executing. This is extremely useful! In this example i used NSLog to report when the block are added to the queue and so this does to be the execution slower and causes the log

ALL BLOCK ADDED

at the end. But as we will see after, without logs it will be wrote at the beginning. Due the fact that we are using a serial queue, the block are executed in the order of adding.

Next:

/* 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] 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] block 3 added

2014-04-08 14:43:16.475 dispex[4346:60b] block 3

2014-04-08 14:43:16.475 dispex[4346:60b] block 4 added

2014-04-08 14:43:16.475 dispex[4346:60b] block 4

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

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

2014-04-08 14:43:16.477 dispex[4346:60b] block 7

2014-04-08 14:43:16.477 dispex[4346:60b] block 8 added

2014-04-08 14:43:16.478 dispex[4346:60b] block 8

2014-04-08 14:43:16.478 dispex[4346:60b] block 9 added

2014-04-08 14:43:16.478 dispex[4346:60b] block 9

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

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

2014-04-08 14:43:16.479 dispex[4346:60b] ALL BLOCK ADDED TO THE QUEUE --> FUNCTION RETURNED

In this example we are using dispatch_sync function with a serial queue. It's very easy to see that all block are added when the previous block finish to be executed. This is a characteristic of dispatch_sync. In other words the function doesn't return until the block finish to be executed. Due the fact that is a serial queue, the order also here is respected.

Next:

/* 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] ALL BLOCK ADDED TO THE QUEUE --> FUNCTION RETURNED

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

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

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

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

2014-04-08 14:43:16.483 dispex[4346:3703] block 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

As i said before, here i show how work dispatch_async but with a concurrent queue. It's really interesting because without NSLog to show when the block is added, you can see how ALL BLOCKS are added before that the first block is executed. This behaviour is not constant. Can happen that block1 is executed and immediately after the dispatch_async finish to add all blocks to the queue and then continue to execute other blocks. Another thing to note, is that the block are executed concurrently, and so them doesn't respect the order of adding and also this behaviour is not constant but depend from the CPU usage, performance and many other things.

Next:

/* 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] 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] block 3 added

2014-04-08 14:43:16.488 dispex[4346:60b] block 3

2014-04-08 14:43:16.488 dispex[4346:60b] block 4 added

2014-04-08 14:43:16.488 dispex[4346:60b] block 4

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

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

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

2014-04-08 14:43:16.490 dispex[4346:60b] block 8 added

2014-04-08 14:43:16.491 dispex[4346:60b] block 8

2014-04-08 14:43:16.491 dispex[4346:60b] block 9 added

2014-04-08 14:43:16.491 dispex[4346:60b] block 9

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

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

2014-04-08 14:43:16.492 dispex[4346:60b] ALL BLOCK ADDED TO THE QUEUE --> FUNCTION RETURNED

Finally, here we used dispatch_sync with concurrent queue. It seems perfectly equal to the couple sync/serial. In this case is so. This behaviour is due the fact that also if the queue is concurrent, it haven't got other block to execute because we are using the synchronous dispatcher and so, it wait to add the next block until the actual doesn't finish to be executed. This type of couple (sync/concurrent) is useful if we are also adding to the queue, blocks with dispatch_async. In that case the dispatcher could have other blocks added to the queue to be executed.

Hope that this mini demonstration has been useful ;)

Cheers!

这篇关于如何混合调度工作时同步/异步串行/并行队列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆