Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapakah had penimbal Go Channel tidak menulis/membaca dengan betul?

Mengapakah had penimbal Go Channel tidak menulis/membaca dengan betul?

WBOY
WBOYke hadapan
2024-02-09 10:30:19423semak imbas

为什么Go Channel的缓冲区不能正确限制写入/读取?

editor php Youzi akan menjawab soalan biasa dalam artikel ini: "Mengapa penampan Saluran Go tidak mengehadkan penulisan/pembacaan dengan betul?" Apabila kami menggunakan Saluran dengan penimbal, kami menjangkakan dapat mengawal kelakuan program dengan mengehadkan bilangan operasi tulis atau baca. Walau bagaimanapun, sebenarnya, penimbal Saluran tidak boleh secara langsung mengehadkan bilangan operasi tulis/baca. Punca dan penyelesaian kepada masalah ini akan dihuraikan di bawah.

Kandungan soalan

Saya cuba berkomunikasi antara dua rutin pergi menggunakan saluran. Mula-mula, saya mencipta saluran integer dan kemudian menyerahkannya sebagai parameter kepada rutin pergi yang mencetak urutan nombor dari 0 hingga 10. Output program ini tidak masuk akal.

Ini adalah kod utama:

func worker(identifier string, ch chan<- int) {
    fmt.printf("entering worker %s\n", identifier)
    for i := 0; i < 10; i++ {
        fmt.printf("writing %d\n", i)
        ch <- i
    }

    fmt.printf("exiting worker %s\n", identifier)

    close(ch)
}

func main() {
    ch := make(chan int)
    go worker("1", ch)

    for v := range ch {
        fmt.printf("reading %d\n", v)
    }
}

Untuk pelaksanaan kod ini, saya mendapat output berikut:

entering worker 1
writing 0
writing 1
reading 0
reading 1
writing 2
writing 3
reading 2
reading 3
writing 4
writing 5
reading 4
reading 5
writing 6
writing 7
reading 6
reading 7
writing 8
writing 9
reading 8
reading 9
exiting worker 1

Perhatikan bahawa terdapat dua pelaksanaan tulis diikuti oleh dua pelaksanaan baca.

Nanti saya tetapkan saiz buffer untuk mencapai fungsi berikut:

func main() {
    ch := make(chan int, 3) // <= buffer
    go worker("1", ch)

    for v := range ch {
        fmt.printf("reading %d\n", v)
    }

}

Kemudian, kita mendapat output berikut:

Entering worker 1
Writing 0
Writing 1
Writing 2
Writing 3
Writing 4
Reading 0
Reading 1
Reading 2
Reading 3
Reading 4
Writing 5
Writing 6
Writing 7
Writing 8
Writing 9
Reading 5
Reading 6
Reading 7
Reading 8
Reading 9
Exiting worker 1

Perhatikan bahawa kini kami mempunyai 5 pelaksanaan tulis dan kemudian 5 pelaksanaan baca.

Setelah kami mempunyai kod dan output, persoalan terakhir timbul: mengapa pelaksanaan hukuman ini berkelakuan seperti yang mereka lakukan? Pertama, bukankah ia sepatutnya hanya membaca dan menulis satu nombor pada satu masa? Di luar itu, mengapa pelaksanaan kedua membaca dan menulis 5 nombor setiap kali dan bukannya 3 (kerana itu saiz penimbal)?

Penyelesaian

Anda semakin keliru apabila mencetak mesej dan apabila membaca atau menulis nombor daripada saluran.

Apabila penulisan berlaku, tiada mesej "tulis" berlaku. Ia berlaku pada satu ketika antara penulisan. Begitu juga, mesej "membaca" berlaku pada satu ketika antara bacaan.

Berikut ialah satu cara untuk mengatur coretan kod pertama, yang menghasilkan output yang ditunjukkan:

  • Terutamanya cuba baca, kemudian sekat.
  • Kakitangan mencetak "Menulis 0".
  • Pekerja menulis 0 dan bacaan utama.
  • Pekerja mencetak "Tulisan 1".
  • Benang pekerja cuba menulis 1, tetapi telah disekat.
  • Terutamanya cetak "Membaca 0".
  • Isi utama ialah 1.
  • Cetakan utama "Bacaan 1".
  • Terutamanya cuba baca, kemudian sekat.

Kawalan sentiasa dihantar antara utama dan Pekerja seperti ini, masing-masing mencetak 2 mesej sebelum menyekat.

Begitu juga, klip kedua anda boleh disusun seperti ini:

  • Terutamanya cuba baca, kemudian sekat.
  • Pekerja mencetak "Menulis 0" dan menghantar 0 terus ke utama.
  • Pekerja mencetak "Penulisan 1" dan penimbal 1.
  • Pekerja mencetak "Penulisan 2" dan penimbal 2.
  • Pekerja mencetak "Penulisan 3" dan penimbal 3.
  • Benang pekerja mencetak "Menulis 4" dan menyekat percubaan untuk menghantar 4.
  • utama melengkapkan bacaan yang disekat dan mencetak "Membaca 0".
  • utama membaca buffer 1 dan mencetak "Bacaan 1".
  • utama membaca buffered 2 dan mencetak "Reading 2".
  • utama membaca buffered 3 dan mencetak "Reading 3".
  • Bacaan utama Pekerja menyekat 4 dan mencetak "Membaca 4".
  • Terutamanya cuba baca, kemudian sekat.
  • Pelaksanaan kembali kepada Pekerja...

Atas ialah kandungan terperinci Mengapakah had penimbal Go Channel tidak menulis/membaca dengan betul?. 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