Rumah > Artikel > pembangunan bahagian belakang > Mengapa saluran tidak mengambil nilai yang diisytiharkan terakhir?
Dalam PHP, saluran ialah konsep penting yang digunakan dalam pengaturcaraan serentak. Ia membenarkan operasi komunikasi dan penyegerakan antara gorouti yang berbeza. Walau bagaimanapun, soalan biasa ialah: "Mengapa saluran tidak mengambil nilai yang diisytiharkan terakhir?" Apabila saluran menerima operasi, ia akan menyekat menunggu pengirim menghantar data. Apabila pengirim telah selesai menghantar data, penerima boleh meneruskan pelaksanaan. Oleh itu, nilai saluran ditentukan apabila penghantar menghantar data, bukan apabila penerima menerima data. Ini adalah untuk memastikan kebolehpercayaan dan konsistensi komunikasi. Oleh itu, walaupun nilai yang diisytiharkan terakhir telah berubah apabila penerima menerimanya, saluran masih akan mengambil nilai apabila ia dihantar. Melakukannya mengelakkan ketidakkonsistenan data dan kekeliruan serta memastikan kebolehpercayaan dan ketepatan komunikasi.
Saya cuba memahami saluran. Dalam kod ini, saya mengisytiharkan nilai dari 1 hingga 10. Nilai pengisytiharan akhir ialah 10, tetapi apabila saya mencetaknya, ia sentiasa mengembalikan nilai dua pengisytiharan sebelum before(8) . Saya akan gembira jika seseorang boleh menjelaskannya.
func main() { channel := make(chan int, 3) isOver := make(chan bool) go func() { for val := range channel { fmt.Println(val) } isOver <- true }() channel <- 1 channel <- 2 channel <- 3 channel <- 4 channel <- 5 channel <- 6 channel <- 7 channel <- 8 channel <- 9 channel <- 10 close(channel) fmt.Println("Channel Value is: ", <-channel) <-isOver }
Apabila saya menukar pengisytiharan kepada 8, ia mengembalikan nilai dua pengisytiharan sebelumnya, iaitu 6.
Kerana anda menetapkan 3 saiz penimbal untuk saluran!
Nota: contoh anda mempunyai output yang berbeza dalam sistem pengendalian yang berbeza (cth. Saya mendapat Channel 值为:0
)
Tetapkan masa. Hibernate dalam kod anda dan lihat apa yang berlaku. Dalam kod anda:
<code>func main() { channel := make(chan int) isOver := make(chan bool) go func() { for val := range channel { fmt.Println(val) // sleep 1 second time.Sleep(1 * time.Second) } isOver <- true }() channel <- 1 channel <- 2 channel <- 3 channel <- 4 channel <- 5 channel <- 6 channel <- 7 channel <- 8 channel <- 9 channel <- 10 close(channel) fmt.Println("Channel Value is: ", <-channel) <-isOver } </code>
Keluaran ialah:
1 2 3 4 5 6 7 Channel Value is: 8 9 10
Nota: Cara yang lebih baik untuk memahami perkara yang berlaku dalam kod anda adalah dengan mengikuti langkah demi langkah.
Apa yang berlaku? Lihat jejak ini:
1 // print 1 and sleep 1s 2,3,4 // stop for get values 3,4 // print 2 and sleep 1 3,4,5 // stop for get value 4,5 // print 3 and sleep 1 4,5,6 // stop for get value 5,6 // print 4 and sleep 1 5,6,7 // stop for get value 6,7 // print 5 and sleep 1 6,7,8 // stop for get value 7,8 // print 6 and sleep 1 7,8,9 // stop for get value 8,9 // print 7 and sleep 1 8,9,10 // stop for get value // close channel // in this line get value : fmt.Println("Channel Value is: ", <-channel) 9,10 // before get value 10 // get 9 and sleep 1 // get 10 and sleep 1 // isdone send signal true
Dalam kod penjejakan, apabila saluran mendapat nilai pokok 8,9,10, saluran ditutup, dalam langkah 2 sesuatu berlaku:
1 - jika goroutine mendapat semua nilai dengan cepat (nilai saluran ialah: 0)
2 - Jika goroutine sibuk (nilai saluran ialah: 7 atau 8 atau 9 atau 10)
Lihat soalan ini untuk mendapatkan butiran: Bila menggunakan saluran penimbal Dan lihat laman web ini untuk pemahaman yang lebih baik: LINK
Atas ialah kandungan terperinci Mengapa saluran tidak mengambil nilai yang diisytiharkan terakhir?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!