Deadlock tritt bei der rekursiven/parallelen Implementierung der Zusammenführungssortierung in Golang auf

WBOY
Freigeben: 2024-02-10 13:15:08
nach vorne
437 Leute haben es durchsucht

golang 中合并排序的递归/并行实现中出现死锁

Der PHP-Editor Xigua hat festgestellt, dass bei Verwendung von Rekursion oder paralleler Implementierung der Zusammenführungssortierung in Golang Deadlock-Probleme auftreten können. Merge Sort ist ein häufig verwendeter Sortieralgorithmus, der ein großes Array zum Sortieren effektiv in mehrere kleine Arrays aufteilen und diese dann zusammenführen kann. Wenn Sie jedoch bei der gleichzeitigen Programmierung in Golang nicht auf die Steuerung der Synchronisation zwischen Goroutinen achten, kann es zu einem Deadlock kommen. In diesem Artikel wird dieses Problem im Detail untersucht und Lösungen bereitgestellt.

Frageninhalt

Ich versuche, mehr über Parallelität in Golang zu erfahren, also versuche ich, den MergeSort-Algorithmus zu verbessern, um eine gleichzeitige Sortierung durchzuführen.

Meine Idee ist es, jedes Mal, wenn ich das Array in zwei teile, eine Goroutine zu erstellen, daher lautet mein Code wie folgt:

func mergeSort(arr []int) []int {
    if len(arr) <= 1 {
        return arr
    }

    mid := len(arr) / 2
    left := arr[:mid]
    right := arr[mid:]

    orderedLeft := make(chan []int)
    orderedRight := make(chan []int)

    var wg sync.WaitGroup

    wg.Add(2)
    go func() {
        defer wg.Done()

        left = mergeSort(left)
        orderedLeft <- left
    }()

    go func() {
        defer wg.Done()
        right = mergeSort(right)
        orderedRight <- right
    }()

    wg.Wait()

    close(orderedLeft)
    close(orderedRight)

    left = <-orderedLeft
    fmt.Println(left)
    right = <-orderedRight
    fmt.Println(right)

    return merge(left, right)
}
Nach dem Login kopieren

Aber ich habe einen schwerwiegenden Fehler gemacht:

fatal error: all goroutines are asleep - deadlock!
Nach dem Login kopieren

Was habe ich falsch gemacht?

Workaround

kann etwas verwirrend sein, da Sie zwei Parallelitätsmodi mischen. Ich bin gleich da.

Wenn Sie einen ungepufferten Kanal verwenden, blockiert die Sender-Goroutine, bis die Empfänger-Goroutine bereit ist, den Wert zu empfangen. In diesem Fall wartet die Haupt-Goroutine auf die Verwendung durch zwei Goroutinen wg.Wait() 完成,而两个 Goroutine 正在尝试将其结果发送到通道 orderedLeftorderedRight. Da die Haupt-Goroutine diese Werte jedoch nicht aktiv vom Kanal empfängt, ist die Goroutine blockiert und kann nicht bis zum Abschluss fortgesetzt werden.

Sie können dieses Problem leicht lösen, indem Sie den Kanal puffern: orderedRight := make(chan []int, 1).

Sie können jedoch Kanäle oder WaitGroups verwenden, anstatt sie zu mischen, was in diesem Fall nicht erforderlich ist:

func mergeSort(arr []int) []int {
    if len(arr) <= 1 {
        return arr
    }

    mid := len(arr) / 2
    left := arr[:mid]
    right := arr[mid:]

    var wg sync.WaitGroup

    wg.Add(2)
    go func() {
        defer wg.Done()
        left = mergeSortWg(left)
    }()

    go func() {
        defer wg.Done()
        right = mergeSortWg(right)
    }()

    wg.Wait()

    return merge(left, right)
}
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonDeadlock tritt bei der rekursiven/parallelen Implementierung der Zusammenführungssortierung in Golang auf. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!