Rumah >pembangunan bahagian belakang >Golang >Mengapa Pesanan Keluaran Saluran Tidak Dibuffer Golang Nampak Berlawanan?

Mengapa Pesanan Keluaran Saluran Tidak Dibuffer Golang Nampak Berlawanan?

Mary-Kate Olsen
Mary-Kate Olsenasal
2024-12-16 21:15:12317semak imbas

Why Does Golang's Unbuffered Channel Output Order Seem Counterintuitive?

Memahami Susunan Output Saluran di Golang

Di Golang, saluran tanpa buffer menyediakan mekanisme komunikasi yang boleh dipercayai antara goroutine. Walau bagaimanapun, tertib keluaran mereka kadangkala boleh mengelirukan. Pertimbangkan kod berikut:

func main() {
  messages := make(chan string)
  go func() { messages <- "hello" }()
  go func() { messages <- "ping" }()
  msg := <-messages
  msg2 := <-messages
  fmt.Println(msg)
  fmt.Println(msg2)
}

Apabila menjalankan kod ini, ia secara konsisten mencetak "ping" diikuti dengan "hello." Ini mungkin kelihatan berlawanan dengan intuitif, kerana seseorang mungkin menjangkakan output sepadan dengan susunan goroutin dicipta.

Untuk memahami sebab perkara ini berlaku, adalah penting untuk diingat bahawa saluran ialah saluran paip komunikasi, manakala goroutin mewakili tugas selari. Urutan pelaksanaan goroutine tidak dijamin, walaupun ia dicipta dalam urutan tertentu.

Dalam kes ini, penjadual mungkin telah menjadualkan goroutine yang menghantar "ping" sebelum yang menghantar "hello." Apabila penerima pertama (iaitu, msg := <-messages) tersedia, ia akan menerima mesej daripada goroutine "ping" yang telah dijadualkan.

Setelah menerima mesej pertama, program akan terus melaksanakan sehingga penerima kedua (msg2 := <-message) tersedia. Pada ketika ini, mesej "hello" sedia untuk dihantar, dan ia akan diterima sebagai mesej kedua.

Oleh itu, susunan output ditentukan oleh perintah pelaksanaan goroutine yang menulis ke saluran , bukan susunan ia dibuat atau susunan mesej dibaca daripada saluran. Untuk mengesahkan ini, seseorang boleh menambah pernyataan Println pada goroutine, seperti yang dicadangkan dalam jawapan yang disediakan:

...
func() { messages <- "hello"; fmt.Println("Hello sent") }()
func() { messages <- "ping"; fmt.Println("Ping sent") }()
...

Ini akan mengeluarkan:

Hello sent
Ping sent
ping
hello

Ini mengesahkan bahawa mesej telah dihantar dan dicetak dalam susunan yang sama.

Atas ialah kandungan terperinci Mengapa Pesanan Keluaran Saluran Tidak Dibuffer Golang Nampak Berlawanan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn