0{"/> 0{">

Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Ralat maut: semua goroutine sedang tidur - kebuntuan! Perlaksanaan ralat

Ralat maut: semua goroutine sedang tidur - kebuntuan! Perlaksanaan ralat

王林
王林ke hadapan
2024-02-10 16:42:19999semak imbas

致命错误:所有 goroutine 都在睡觉 - 死锁!错误执行

editor php Strawberry akan memperkenalkan anda kepada ralat pengaturcaraan biasa dalam artikel ini: ralat maut: "Semua gorouti sedang tidur - kebuntuan! Ralat pelaksanaan". Ini adalah salah satu kesilapan biasa dalam bahasa Go dan salah satu cabaran yang sering dihadapi oleh pembangun. Dalam artikel ini, kami akan menerangkan punca dan penyelesaian ralat ini secara terperinci untuk membantu semua orang memahami dan menangani masalah ini dengan lebih baik. Sama ada anda seorang pemula atau pembangun berpengalaman, anda akan mendapat maklumat dan petua berharga daripada artikel ini. Mari kita meneroka bersama-sama!

Kandungan soalan

Saya sangat baru untuk concurrency in go, jadi saya mencuba contoh dengan saluran dan goroutine. Saya mahu model pengeluar-pengguna. Fungsi pengeluar sentiasa memberikan rentetan rawak dan pengguna mengubah suainya dengan menjadikannya huruf besar. Saya mahu menjalankannya untuk masa yang terhad (2 saat).

package main

import (
    "fmt"
    "math/rand"
    "strings"
    "time"
)

func producer(x []string, c chan string) {
    i := 1
    for i > 0 {
        randomIndex := rand.Intn(len(x))
        pick := x[randomIndex]
        c <- pick
    }
}

func consumer(x string, c chan string) {
    x1 := strings.ToUpper(x)
    c <- x1
}

func main() {

    s := []string{"one", "two", "three", "four"}
    c1 := make(chan string)
    d1 := make(chan string)
    go producer(s, c1)
    go consumer(<-c1, d1)

    stop := time.After(2000 * time.Millisecond)
    for {
        select {
        case <-stop:
            fmt.Println("STOP AFTER 2 SEC!")
            return
        default:
            fmt.Println(<-d1)
            time.Sleep(50 * time.Millisecond)
        }
    }
}

Saya hanya menerima satu elemen tatasusunan dan beberapa ralat. Apakah perubahan yang perlu dibuat untuk menjadikan contoh ini berfungsi?

Keluaran:

Dua

RALAT MAUT: Semua gorouti sedang tidur - kebuntuan!

goroutine 1 [chan receive]: utama.utama()

Coroutine 6 [hantar chan]: main.producer({0xc00004e040, 0x4, 0x0?}, 0x0?) Dicipta oleh utama. utama Keluar Status 2

Penyelesaian

Pengguna anda harus berjalan dalam gelung, ini telah disebut.

Tukar parameter pertama pengguna supaya ia chan字符串 bukannya rentetan. Dengan cara ini pengeluar boleh terus menulis ke saluran ini untuk pengguna menerbitkan di saluran lain sehingga had masa tamat.

func consumer(consumechan chan string, outch chan string) {
    for {
        select {
        case s := <- consumechan:
            s = strings.toupper(s)
            outch <- s
        }
    }
}

Sekarang, apabila memanggil go consumer() 之前的主函数中,您正在等待生产者对 c1 通道的第一个响应。不要这样做,而是将 c1 saluran diluluskan sebagai hujah pertama.

func main() {
    s := []string{"one", "two", "three", "four"}
    c1 := make(chan string)
    d1 := make(chan string)
    go producer(s, c1)
    go consumer(c1, d1)

    stop := time.After(2000 * time.Millisecond)
    for {
        select {
        case <-stop:
            fmt.Println("STOP AFTER 2 SEC!")
            return
        case response := <- d1:
            fmt.Println(response)
            time.Sleep(50 * time.Millisecond)
        }
    }
}

Ini sepatutnya menunjukkan pengeluar terus menulis nombor rawak pada saluran c1 dan pengguna terus menulis semua teks huruf besar pada saluran d1 sehingga 2 saat tamat.

Atas ialah kandungan terperinci Ralat maut: semua goroutine sedang tidur - kebuntuan! Perlaksanaan ralat. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam