3

In my program I need two tasks to run simultaneously in the background. To do that i have used concurrent queues as below,

let concurrentQueue = DispatchQueue(label: "concurrentQueue", qos: .utility, attributes: .concurrent)

concurrentQueue.async {
    for i in 0 ..< 10{
        print(i)
    }
}

concurrentQueue.async {
    for i in (0 ..< 10).reversed(){
        print(i)
    }
}

Here I need the output like this,

0
9
1
8
2
7
3
6
4
5
5
4
6
3
7
2
8
1
9
0

But what I get is,

enter image description here

I referred below tutorial in order to have some basic knowledge about Concurrent Queues in Swift 3
https://www.appcoda.com/grand-central-dispatch/

Can someone tell me what is wrong with my code? or else is it the result I should get? Is there any other ways to get my thing done? Any help would be highly appreciated.

4

2 回答 2

4

您的代码示例没有任何问题。这是将两个任务提交到并发队列的正确语法。

问题是您一定会看到它们同时运行的期望。有两个问题可能会影响这一点:

  1. 第一个调度的任务可以运行得如此之快,以至于它恰好在第二个任务开始之前完成。如果你放慢它们的速度,你会看到你的并发行为:

    let concurrentQueue = DispatchQueue(label: Bundle.main.bundleIdentifier! + ".concurrentQueue", qos: .utility, attributes: .concurrent)
    
    concurrentQueue.async {
        for i in 0 ..< 10 {
            print("forward: ", i)
            Thread.sleep(forTimeInterval: 0.1)
        }
    }
    
    concurrentQueue.async {
        for i in (0 ..< 10).reversed() {
            print("reversed:", i)
            Thread.sleep(forTimeInterval: 0.1)
        }
    }
    

    您永远不会sleep在生产代码中,但出于教学目的,它可以更好地说明问题。

    您也可以省略sleep调用,而只是显着增加数字(例如1_00010_000),您可能会开始看到并发处理正在发生。

  2. 您的设备可能会受到资源限制,从而阻止它同时运行代码。设备具有有限数量的 CPU 内核来运行并发任务。仅仅因为您将任务提交到并发队列,并不意味着设备能够同时运行这两个任务。这取决于硬件以及该设备上运行的其他内容。

    顺便说一句,请注意,您可能会在模拟器(使用 Mac 的 CPU,可能正在运行许多其他任务)上看到与在设备上不同的行为。如果您还没有,您可能需要确保在实际设备上测试此行为。


另请注意,您说您“需要”输出以print在两个队列之间交替语句。虽然您的教程中的屏幕快照表明这应该是意料之中的,但您绝对不能保证会出现这种情况。

如果你真的需要它们来回交替,你必须添加一些机制来协调它们。您可以使用信号量(我不愿意仅仅因为它们是问题的常见来源,特别是对于新开发人员而言)或具有依赖关系的操作队列。

于 2017-09-25T18:35:07.500 回答
1

也许你可以尝试使用信号量。

    let semaphore1 = DispatchSemaphore(value: 1)
    let semaphore2 = DispatchSemaphore(value: 0)
    concurrentQueue.async {
    for i in 0 ..< 10{
    semaphore1.wait()
    print(i)
    semaphore2.signal()
    }
    }

    concurrentQueue.async {

    for i in (0 ..< 10).reversed(){
    semaphore2.wait()
    print(i)
    semaphore1.signal()
    }
    }
于 2019-01-19T16:02:05.103 回答