Ios 调度队列同步并发

Ios 调度队列同步并发,ios,swift,grand-central-dispatch,Ios,Swift,Grand Central Dispatch,好吧,我已经回答了大量的问题和答案,我知道对它的理解,但是当我尝试一些代码时,我得到了一些不符合这些理论的结果 到目前为止,我的理解是: 同步:一旦执行块内的所有任务,控件将返回 异步:控件将在命中块后立即返回 这是看起来不错的部分。 现在是棘手的部分 串行:任务将在块内以串行方式执行。 问题1:这是否适用于区块内的任务?因为它已经在所有场景中发生。同样对于同步串行队列,在不同的块中添加任务并不重要,因为一旦完成第一个任务,控制就会返回 乙二醇- 预期输出:ABC*10,XYZ*10 这很好 现

好吧,我已经回答了大量的问题和答案,我知道对它的理解,但是当我尝试一些代码时,我得到了一些不符合这些理论的结果

到目前为止,我的理解是:

  • 同步:一旦执行块内的所有任务,控件将返回
  • 异步:控件将在命中块后立即返回
  • 这是看起来不错的部分。 现在是棘手的部分

  • 串行:任务将在块内以串行方式执行。 问题1:这是否适用于区块内的任务?因为它已经在所有场景中发生。同样对于同步串行队列,在不同的块中添加任务并不重要,因为一旦完成第一个任务,控制就会返回
  • 乙二醇-

    预期输出:ABC*10,XYZ*10 这很好

    现在,当我引入并发串行Q时,输出是相同的。所以我的问题是,正如并发队列所说的,任务将在同一时间或同时完成,它不会发生

    例如

    输出:XYZ*10,ABC*10,HHH*10,XXX*10

    所以,同步并发队列的行为类似于串行队列,进行并发操作的唯一方法是,如果我们在操作之间抛出一个异步队列。
    因此,从这一点我无法理解,并发类型的串行队列的目的是什么

    如果有人能给出代码示例,我将不胜感激,因为我已经知道了它的理论和工作原理。
    非常感谢。

    要了解串行/并发队列和同步/异步方法之间的区别,以及它们是如何分配到队列的,请尝试在游戏场上播放下一个片段

    import PlaygroundSupport
    import Dispatch
    PlaygroundPage.current.needsIndefiniteExecution = true
    
    let q = DispatchQueue(label: "concurrect queue", qos: .background, attributes: .concurrent)
    
    func runner0(queue: DispatchQueue) {
        for _ in 1..<10 {
            let result = queue.sync { ()->Int in
                usleep(100)
                return 0
            }
            DispatchQueue.main.async {
                print(result, "-")
            }
        }
    }
    
    func runner1(queue: DispatchQueue) {
        for _ in 1..<10 {
            let result = queue.sync { ()->Int in
                usleep(100)
                return 1
            }
            DispatchQueue.main.async {
                print("-", result)
            }
        }
    }
    
    let arr = [runner0, runner1]
    
    DispatchQueue.concurrentPerform(iterations: 2) { (i) in
        arr[i](q)
    }
    
    让我们通过更改队列的定义,使队列成为串行队列

    let q = DispatchQueue(label: "serial queue")
    
    并比较我们得到的结果

    0 -
    - 1
    0 -
    - 1
    0 -
    - 1
    0 -
    - 1
    0 -
    - 1
    0 -
    - 1
    0 -
    - 1
    0 -
    - 1
    0 -
    - 1
    

    实际上,在您的代码中,当您在并发队列(第二个代码段)中执行任务时,您是通过sync block分派任务的,因此这将根据sync行为阻塞当前线程

    “同步:一旦执行块内的所有任务,控件将返回。”

       let syncConc = DispatchQueue(label:"con",attributes:.concurrent)
    
       syncConc.sync{
          for _ in 0...10{
            print("XYZ")
          }
    
          for _ in 0...10{
            print("ABC")
          }
       }
    
    
       syncConc.sync{
          for _ in 0...10{
            print("HHH")
          }
    
          for _ in 0...10{
            print("XXX")
          }
       }
    
    因此,在这种情况下,首先,suncConc队列将调度第一个同步块,现在由于它是阻塞调用,下一个任务不会立即被调度,它将被调度,一旦第一个任务完成,然后它将在suncConc队列中被调度,并再次使用阻塞调用执行

    现在,让我来回答你的问题

    “现在,当我引入并发串行Q时,输出是相同的。因此,我的问题是,正如并发队列所说,任务将在同一时间或同时完成,它不会发生。”

    是的,同步操作也可以并发执行,但只有当您在不阻塞当前线程的情况下立即分派两个调用时才可能。检查以下代码段,这两个同步任务是从不同的队列分派的,因此它将并发执行

        let syncConc = DispatchQueue(label:"con",attributes:.concurrent)
    
    
        DispatchQueue.global(qos: .utility).async {
            syncConc.sync{
                for _ in 0...10{
                    print("XYZ - \(Thread.current)")
                }
                for _ in 0...10{
                    print("ABC - \(Thread.current)")
                }
            }
        }
    
    
        DispatchQueue.global(qos: .userInitiated).async {
            syncConc.sync{
                for _ in 0...10{
                    print("HHH - \(Thread.current)")
                }
    
                for _ in 0...10{
                    print("XXX - \(Thread.current)")
                }
            }
        }
    

    执行代码&看看魔术所有的理论都会像预期的那样应用:)

    问题是你把队列类型和执行模型搞混了

    有串行队列和并发队列,您可以同步或异步地向这两种类型分派任务

    队列可以是:

    • 串行->一次只执行一个任务
    • 并发->可以同时运行多个任务
    我们可以将任务提交到队列:

    • 同步->调用方需要等待该任务返回
    • 异步->调用方代码无需等待任务完成即可重新获得控制权
    总而言之:

    • 队列的串行或并发类型决定它是否可以同时执行一个或多个任务
    • 同步或异步调度任务可确定调用方的代码何时恢复控制

    串行队列并发类型的目的是什么???您是如何推断串行队列可以是并发的?队列是串行的还是并发的。这很容易,不必去弄清楚?因为我们有使串行队列并发的选项。我的问题是,在单个串行队列中添加多个任务,这应该是o并发。在文档中,它说这应该发生,在所有的解释性教程中,它也这样说,但当我尝试做同样的事情时,它不会发生。可能是我遗漏了什么信息来自哪里?如果所有分派给它的任务都是串行执行的,那么队列是串行的。如果所有ta都是串行执行的,那么队列是并发的发送到它的sks是并发执行的。请再次检查文档或查看抱歉,我的意思是:同步-并发队列,这就是我的问题所在。我确实得到了队列类型:串行和并发。但是,当我创建一个并发和同步的队列时,它的行为与所说的不一样。希望我能澄清r confusionIt does.Sync意味着,将任务分派到队列的线程被阻塞,直到任务完成执行(在某个线程上)。您可以同时从不同线程分派更多同步任务。所有任务都将同时执行。在您的示例中,您从main分派任务时,main被阻止,然后您分派其他任务…我有点不明白为什么会这样做?在全局队列中分派并发同步任务,因此我们首先需要并发同步任务吗?没有“并发同步任务”这样的东西。队列可以是并发的,任务可以同步或异步地分派到队列。这是一个很好的答案谢谢@michaelxing。我想知道为什么它被否决了。
    0 -
    - 1
    0 -
    - 1
    0 -
    - 1
    0 -
    - 1
    0 -
    - 1
    0 -
    - 1
    0 -
    - 1
    0 -
    - 1
    0 -
    - 1
    
       let syncConc = DispatchQueue(label:"con",attributes:.concurrent)
    
       syncConc.sync{
          for _ in 0...10{
            print("XYZ")
          }
    
          for _ in 0...10{
            print("ABC")
          }
       }
    
    
       syncConc.sync{
          for _ in 0...10{
            print("HHH")
          }
    
          for _ in 0...10{
            print("XXX")
          }
       }
    
        let syncConc = DispatchQueue(label:"con",attributes:.concurrent)
    
    
        DispatchQueue.global(qos: .utility).async {
            syncConc.sync{
                for _ in 0...10{
                    print("XYZ - \(Thread.current)")
                }
                for _ in 0...10{
                    print("ABC - \(Thread.current)")
                }
            }
        }
    
    
        DispatchQueue.global(qos: .userInitiated).async {
            syncConc.sync{
                for _ in 0...10{
                    print("HHH - \(Thread.current)")
                }
    
                for _ in 0...10{
                    print("XXX - \(Thread.current)")
                }
            }
        }