并发调度队列没有被阻塞

Concurrent Dispatch Queue not getting blocked

我正在读一本 iOS 的书,上面写着 "dispatch_sync function blocks the concurrent queue to which the block is submitted i.e it makes the queue wait"。基于这个概念,我创建了自己的示例,如 follows.The 以下代码片段是在 "viewDidLoad" 方法

中编写的

dispatch_queue_t concQueue1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

void (^secondBlock)(void) =^( void)
{

    //Second Block
    for (int count=0; count<1000; count++)
    {

        if( [NSThread currentThread] == [NSThread mainThread ] )
        {
            NSLog(@"2 block main Thread") ;
        }
        else
        {

            NSLog(@"2  block other THREAD") ;
        }
    }

};



void (^firstBlock)(void) =^( void)
{
    //First Block
    for (int count=0; count<100; count++)
    {

        if( [NSThread currentThread] == [NSThread mainThread ] )
        {
            NSLog(@"1 block  main Thread") ;
        }
        else
        {

            NSLog(@"1 block other THREAD") ;
        }
    }


    dispatch_sync(concQueue1, secondBlock) ;

};



dispatch_async(concQueue1,firstBlock);

//Making the main thread sleep for some time
[NSThread sleepForTimeInterval:0.1] ;

dispatch_async( concQueue1, ^(void) {

    //Third Block
    for (int count=0; count<1000; count++)
    {

        if( [NSThread currentThread] == [NSThread mainThread ] )
        {
            NSLog(@"3 block main Thread") ;
        }
        else
        {

            NSLog(@"3 block other THREAD") ;
        }
    }

});

我让主线程休眠一段时间,以便执行 "first block " 中的 dispatch_sync 函数。我得到的输出是这样的。我正在显示输出的一部分。

GCDExamples[2459:554259] 2 块其他线程

.

.

.

GCDExamples[2459:554259] 2 块其他线程

GCDExamples[2459:554256] 3 块其他线程

GCDExamples[2459:554256] 3 块其他线程

GCDExamples[2459:554259] 2 block other THREAD //先点t

GCDExamples[2459:554256] 3 块其他线程

关于输出的一些要点:“3 block other THREAD”和“2 block other THREAD”中显示的输出是该输出行的第一次出现

我的问题: 根据这个概念,因为 dispatch_sync 函数一旦第二个块开始,它应该让队列等待而不是让 "Third block" 开始。但是如前面的输出所示,“2 block other THREAD”跟在“3 block other THREAD”语句在​​ "//Point first" 之后。这表明 dispatch_sync 函数确实不要让队列等待。这怎么可能?? .如果需要请问我任何其他信息。

编辑 1: 我将著名书籍的文字放在这里来解释我的观点。这本书是"iOS 7 Programming cookbook"。正文如下:- "For any task that doesn’t involve the UI, you can use global concurrent queues in GCD. These allow either synchronous or asynchronous execution. But synchronous execution does not mean your program waits for the code to finish before continuing. It simply means that the concurrent queue will wait until your task has finished before it continues to the next block of code on the queue. When you put a block object on a concurrent queue, your own program always continues right away without waiting for the queue to execute the code. This is because concurrent queues, as their name implies, run their code on threads other than the main thread."

正如粗体文字所说,并发队列将等待直到我的任务完成,然后再继续下一个块。我的块打印“2 block other THREAD”应该被允许在“3 block other THREAD”开始之前完成,但情况并非如此我的“2 block other THREAD”再次打印时与“3 block other THREAD”语句混合在一起事实上,我所有的“2 block other THREAD”应该被允许完成,然后“3 block other THREAD”应该跟随。如果需要更多信息,请发表评论。

首先要明白,GCD你得明白同步和异步执行的区别

同步 = 在提交时执行并阻止提交 thread/queue on.This 意味着:

  1. (代码)块仅在队列中轮到它时执行。
  2. (代码)块将阻塞执行队列,其他(代码和同步)块将等待。

基本上块将以 FIFO 格式执行。

异步 = 不管 queue/thread 立即开始执行并且不阻塞 queue/thread。即使队列中正在执行某些操作(同步和异步)也执行。

要了解什么时候出错,我们将通过代码进行工作。

  1. 第 1-19 行 - 定义了 secondBlock
  2. 第 23-43 行 - 定义了 firstBlock
  3. 第47行——dispatch_async()firstBlock(记住:异步执行)
  4. 第41行[firstBlock] dispatch_sync()secondBlock(记住:同步执行)
  5. 第 43 行[firstBlock] - firstBlock 退出
  6. 第 50 行 - 线程休眠 0.1 秒
  7. 第 52 行 - 定义并执行 thirdBlock(记住:异步执行)。

thirdBlock 异步执行并开始执行,即使在 queue.To 上执行了 secondBlock 实现块(代码)排队,我们 dispatch_sync().

备注

这个函数相对于并发操作queue.This意味着dispatch_sync()只会同步到当前队列。在其他线程(例如主线程)上它似乎是异步的。

"dispatch_sync function blocks the concurrent queue to which the block is submitted i.e it makes the queue wait"

如果这本书是这么说的,那就把它扔掉。那是错误的。

同步与异步是关于调用者的。当某些代码调用 dispatch_sync() 时, 该代码 无法继续,直到被分派的任务完成。队列没有被阻塞或被迫等待或类似的事情。

相比之下,当代码调用 dispatch_async() 时,任务被放入队列,调用者继续执行下一步。它不等待分派的任务开始,更不用说完成了。

这与队列是并发的还是串行的完全不同。这种区别属于队列和它们 运行 的任务,但不会直接影响调用者。串行队列一次只会 运行 一项任务。如果其他任务已排队,它们将按严格的顺序等待并运行。

并发队列可以允许多个任务同时 运行,具体取决于可用的系统资源。


使用书中的新引语更新已编辑的问题:

For any task that doesn’t involve the UI, you can use global concurrent queues in GCD. These allow either synchronous or asynchronous execution. But synchronous execution does not mean your program waits for the code to finish before continuing. It simply means that the concurrent queue will wait until your task has finished before it continues to the next block of code on the queue. When you put a block object on a concurrent queue, your own program always continues right away without waiting for the queue to execute the code. This is because concurrent queues, as their name implies, run their code on threads other than the main thread.

这仍然是完全错误的。一部分一部分地看:

But synchronous execution does not mean your program waits for the code to finish before continuing.

这正是 "synchronous execution" 的意思。当您同步提交任务时,提交线程在继续之前等待代码完成。

It simply means that the concurrent queue will wait until your task has finished before it continues to the next block of code on the queue.

没有。并发队列的全部要点是它们等待一个正在运行ning 的任务,然后再开始后续任务。这就是 "concurrent" 的意思。一个并发队列可以运行多个任务并发,同时,同时。

When you put a block object on a concurrent queue, your own program always continues right away without waiting for the queue to execute the code.

不,这是错误的。这完全取决于您使用什么函数将该块放入队列。如果它使用 dispatch_sync(),它会等待队列执行该块。如果它使用 dispatch_async(),它不会等待;它会立即继续。无论队列是串行的还是并发的,都是如此。

This is because concurrent queues, as their name implies, run their code on threads other than the main thread.

除了主队列之外,任何串行或并发队列都可以运行在后台线程上提交给它的块。而且,如果您使用 dispatch_sync() 从主线程向并发队列提交一个块,则该块很可能会在主线程上执行。那是因为 GCD 知道主线程没有做任何其他事情,因为它被阻塞在 dispatch_sync() 调用内部,所以它也可能 运行 那里的阻塞。

换句话说,队列的类型 而不是 决定块 运行 在哪个线程上。

这本书的作者根本不知道s/he在说什么