Mengapa saluran tidak mengambil nilai yang diisytiharkan terakhir?

WBOY
Lepaskan: 2024-02-09 09:15:11
ke hadapan
1130 orang telah melayarinya

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.

Kandungan soalan

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

}
Salin selepas log masuk

Apabila saya menukar pengisytiharan kepada 8, ia mengembalikan nilai dua pengisytiharan sebelumnya, iaitu 6.

Penyelesaian

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>
Salin selepas log masuk

Keluaran ialah:

1
2
3
4
5
6
7
Channel Value is:  8
9
10
Salin selepas log masuk

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
Salin selepas log masuk

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!

Label berkaitan:
sumber:stackoverflow.com
Kenyataan Laman Web ini
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
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!