Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Apabila menggunakan saluran, apakah susunan pelaksanaan goroutine?

Apabila menggunakan saluran, apakah susunan pelaksanaan goroutine?

王林
王林ke hadapan
2024-02-09 13:48:091217semak imbas

使用通道时,goroutine 的执行顺序是什么?

editor php Baicao berada di sini untuk menjawab soalan biasa: "Apabila menggunakan saluran, apakah susunan pelaksanaan goroutine dalam bahasa Go, goroutine ialah utas ringan yang boleh dilaksanakan serentak. Apabila menggunakan saluran untuk komunikasi antara coroutine, operasi terima dan hantar saluran disekat, iaitu, mereka menunggu operasi coroutine lain selesai. Oleh itu, apabila berbilang goroutine mengendalikan saluran pada masa yang sama, perintah pelaksanaannya tidak pasti dan bergantung pada penjadualan setiap coroutine. Ini bermakna adalah mustahil untuk menentukan goroutine mana yang akan dilaksanakan dahulu dan yang akan dilaksanakan kemudian. Ini ditentukan oleh penjadual bahasa Go.

Kandungan soalan

Apakah susunan pelaksanaan goroutine apabila menggunakan saluran? Saya rasa menulis atau membaca saluran menghentikan goroutine semasa. Tetapi kod ujian saya tidak mengikut peraturan ini:

func main() {
    ch := make(chan int)
    go sum(ch, 3)
    fmt.Println("Write number: 10")
    ch <- 10
    fmt.Println("Write number: 20")
    ch <- 20
    fmt.Println("Write number: 30")
    ch <- 30

    fmt.Println("Finish main")
}

func sum(ch chan int, len int) {
    fmt.Println("Func 'sum' start")

    sum := 0
    for i := 0; i < len; i++ {
       fmt.Println("For start")
       num := <-ch
       fmt.Printf("Read from ch: %d\n", num)
       sum += num
       fmt.Println("For finish")
    }

    fmt.Printf("Sum: %d\n", sum)
}

Bagaimana saya rasa aplikasi ini berfungsi:

1.Buat saluran

2 Buat goroutine (bukan dimulakan, hanya dimulakan)

3 Cetak: tulis nombor: 10

4. Rakam ke saluran 10. Fungsi kunci kunci.

5 Yang paling penting kena block. Mulakan jumlah goroutine.

6. Fungsi penjumlahan cetak: Fungsi 'jumlah' bermula

7 Fungsi penjumlahan berjalan dalam gelung dan mencetak: "Untuk bermula"

8 Baca nombor 10 dari "ch" dan cetak: "Baca dari ch: 10"

.

9. Langkah seterusnya. Cetak: "Selesai" dan teruskan dengan lelaran seterusnya.

10. Cetak: "bermula dengan" dan cuba tulis "dengan". Tetapi saluran itu kosong. Hentikan kuota dan masuk ke talian utama

...dan lagi dan lagi.

Lepastu saya nak tengok:

Write number: 10
Func 'sum' start
For start
Read from ch: 10
For finish
For start
Write number: 20
Read from ch: 20
For finish
For start
Write number: 30
Read from ch: 30
For finish
Sum: 60
Finish main

Tetapi, saya nampak:

Write number: 10
Func 'sum' start
For start
Read from ch: 10
For finish
For start
Write number: 20
Write number: 30
Read from ch: 20
For finish
For start
Read from ch: 30
For finish
Sum: 60
Finish main

Bagaimana ini boleh berlaku? Fungsi utama menulis ke saluran dua kali tanpa membaca.

Juga, jika anda menukar bilangan panggilan untuk:

go sum(ch, 2)

Saya tidak mendapat ralat. Tetapi tiada siapa yang membaca mesej terakhir

Contoh: sebelum mesej ini.

Penyelesaian

Gorutin berjalan serentak. Pada sistem dengan berbilang teras, mereka boleh berjalan secara selari. Butiran bergantung pada pelaksanaan penjadual dalam masa jalan Go. Untuk semua maksud dan tujuan, kecuali untuk operasi segerak seperti komunikasi saluran, perkara berlaku dalam susunan rawak.

Ini tidak berlaku dan bukan perkara yang berlaku (selagi saluran tidak ditimbal). Panggilan Println berlaku sebelum operasi penghantaran, dan Goroutine utama menyekat selepas mencetak sehingga jumlah Goroutine sedia untuk diterima.

Sama ada anda melihat "Baca dari ch: 30" dicetak juga secara rawak. Operasi terima yang sepadan mesti berlaku kerana blok utama sehingga ia berlaku. Walau bagaimanapun, main boleh kembali sebelum Println selepas penerimaan berlaku, dan program akan ditamatkan serta-merta apabila utama kembali, tanpa mengira kehadiran mana-mana goroutine lain. Jika saluran ditimbal, kemungkinan ini berlaku meningkat.

Bukan begitu. Jika terdapat hanya dua penerima, ia akan sentiasa membawa kepada kebuntuan: https://go.dev/play/p/ qFVh529mkqR

Atas ialah kandungan terperinci Apabila menggunakan saluran, apakah susunan pelaksanaan goroutine?. 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