并发队列问题 - iOS / Swift

时间:2017-09-25 17:31:05

标签: ios swift3 grand-central-dispatch concurrent-queue

在我的程序中,我需要在后台同时运行两个任务。为此,我使用了如下的并发队列,

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

我需要这样的输出,

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

但我得到的是,

enter image description here

我在下面的教程中提到了一些关于Swift 3中的并发队列的基本知识 https://www.appcoda.com/grand-central-dispatch/

有人可以告诉我我的代码有什么问题吗?或者是我应该得到的结果?还有其他办法让我的事情完成吗?任何帮助将受到高度赞赏。

2 个答案:

答案 0 :(得分: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,这可能会运行许多其他任务),而不是在设备上。您可能希望确保在实际设备上测试此行为,如果您还没有。

  3. 还要注意你说你需要&#34;需要&#34;输出到两个队列之间的备用print语句。虽然您的教程中的屏幕快照表明这应该是预期的,但您绝对不能保证会出现这种情况。

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

答案 1 :(得分:0)

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

fasttext_dir = '/Fasttext'
embeddings_index = {}
f = open(os.path.join(fasttext_dir, 'wiki.en.vec'), 'r', encoding='utf-8')
for line in tqdm(f):
    values = line.rstrip().rsplit(' ')
    word = values[0]
    coefs = np.asarray(values[1:], dtype='float32')
    embeddings_index[word] = coefs
f.close()

print('found %s word vectors' % len(embeddings_index))

embedding_dim = 300

embedding_matrix = np.zeros((max_words, embedding_dim))
for word, i in word_index.items():
    if i < max_words:
        embedding_vector = embeddings_index.get(word)
        if embedding_vector is not None:
            embedding_matrix[i] = embedding_vector