Многопоточность в IOS Swift - PullRequest
0 голосов
/ 26 апреля 2018

Я пытаюсь запустить два потока параллельно. Но, к сожалению, иногда это работает, иногда нет. Вот мой код

 let firstQueue = DispatchQueue(label: "queue1", qos: DispatchQoS.userInitiated)
 let secondQueue = DispatchQueue(label: "queue2", qos: DispatchQoS.userInitiated)
//let firstQueue = DispatchQueue(label: "queue1", qos: DispatchQoS.default , attributes: .concurrent)

    firstQueue.async {
        for i in 0..<10 {
            print("?", i)
        }
    }


    secondQueue.async {
        for i in 20..<30 {
            print("⚪️", i)
        }
    }

Я пробовал все по-другому, но не достиг идеального параллелизма. Первый выход: 0 ⚪️ 20 ? 1 ⚪️ 21 ? 2 ⚪️ 22 ? 3 ⚪️ 23 ? 4 ⚪️ 24 ? 5 ⚪️ 25 ? 6 ⚪️ 26 ? 7 ⚪️ 27 ? 8 ⚪️ 28 ? 9 ⚪️ 29

Вывод SecondTime:

? 0 ? 1 ? 2 ? 3 ? 4 ? 5 ? 6 ? 7 ? 8 ? 9 ⚪️ 20 ⚪️ 21 ⚪️ 22 ⚪️ 23 ⚪️ 24 ⚪️ 25 ⚪️ 26 ⚪️ 27 ⚪️ 28 ⚪️ 29

Ответы [ 3 ]

0 голосов
/ 26 апреля 2018

Вы можете использовать DispatchGroup , также вы должны прочитать больше о GCD, код ниже работает, как и ожидалось, и это решит вашу проблему

let dispatchGroup = DispatchGroup()
let firstQueue = DispatchQueue(label: "queue1", qos: DispatchQoS.userInitiated)
let secondQueue = DispatchQueue(label: "queue2", qos: DispatchQoS.userInitiated)

firstQueue.async(group: dispatchGroup) {
    for i in 0..<10 {
        print("?", i)
    }
    dispatchGroup.leave()
}

secondQueue.async(group: dispatchGroup) {
    dispatchGroup.wait()
    for i in 20..<30 {
        print("⚪️", i)
    }
}

вывод всегда будет таким? 0 ? 1 ? 2 ? 3 ? 4 ? 5 ? 6 ? 7 ? 8 ? 9 ⚪️ 20 ⚪️ 21 ⚪️ 22 ⚪️ 23 ⚪️ 24 ⚪️ 25 ⚪️ 26 ⚪️ 27 ⚪️ 28 ⚪️ 29 100 29

0 голосов
/ 26 апреля 2018

Суть многопоточности заключается в том, что операции будут выполняться параллельно и независимо друг от друга. Это не гарантирует никакой порядок, никакой синхронизации и ничего. Если вам нужно синхронизировать вещи, вам нужно использовать один поток или третий поток, который отправляет работу:

func foo() {
    let firstQueue = DispatchQueue(label: "queue1")
    let secondQueue = DispatchQueue(label: "queue2")

    let mainQueue = DispatchQueue(label: "queueMain")

    var firstQueueOperationsCount: Int = 10
    var secondQueueOperationsCount: Int = 10

    func performOperations() {
        guard max(firstQueueOperationsCount, secondQueueOperationsCount) > 0 else {
            return
        }
        mainQueue.async {
            if firstQueueOperationsCount > secondQueueOperationsCount {
               firstQueueOperationsCount -= 1
                firstQueue.async {
                    print("?")
                    performOperations()
                }
            } else {
                secondQueueOperationsCount -= 1
                secondQueue.async {
                    print("⚪️")
                    performOperations()
                }
            }
        }
    }

    performOperations()
}

Существует множество способов сериализации задач, отправляемых в несколько потоков, и это только один из них. Вы можете попробовать поискать / прочитать в этом направлении, но просто будьте ясны: то, что вы ожидаете от многопоточности, - это НЕ ЧТО ТАКОЕ МУЛЬТИТРЕЙДИНГ. Это не работает таким образом, и это не должно работать таким образом. Как они работают, это то, как мы хотим, чтобы это работало.

Если у вас более конкретная ситуация, я уверен, что сообщество здесь может помочь вам найти хороший подход для ее решения. Но из того, что вы написали, результат не многопоточность, а:

for i in 0..<10 {
    print("?")
    print("⚪️")
}

Он может быть отправлен в другой поток, но это действительно не имеет значения.

0 голосов
/ 26 апреля 2018

Ваш код работает хорошо, но вы должны знать, что у вас нет никакого выбора, чтобы решить, какая часть вашего кода будет выполняться первой, и так как ваш код просто печатает символ и его легкая работа для Вы видите, что несколько раз ваши персонажи печатали по порядку, а иногда не по порядку. Попробуйте дать более тяжелую работу процессору, а затем посмотрите на результаты!

...