Mengapakah kod Go saya mencetak jumlah 10 bilion nombor dan bukannya hanya \'paparkan mesej pertama: hello\'?

DDD
Lepaskan: 2024-10-28 07:49:02
asal
145 orang telah melayarinya

Why does my Go code print the sum of 10 billion numbers instead of just

Go Concurrency dan Kekeliruan Saluran

Masalah

Seorang pengguna cuba memahami Go concurrency dan saluran menggunakan coretan kod berikut:

<code class="go">package main

import "fmt"

func display(msg string, c chan bool) {
    fmt.Println("display first message:", msg)
    c <- true
}

func sum(c chan bool) {
    sum := 0
    for i := 0; i < 10000000000; i++ {
        sum++
    }
    fmt.Println(sum)
    c <- true
}

func main() {
    c := make(chan bool)

    go display("hello", c)
    go sum(c)
    <-c
}</code>
Salin selepas log masuk

Output yang dijangkakan hanyalah "paparkan mesej pertama: hello" kerana fungsi utama harus keluar sebaik sahaja ia menerima data daripada saluran. Walau bagaimanapun, output sebenar juga termasuk jumlah 10 bilion nombor.

Jawapan

Isu utama dalam kod ialah penjadual boleh memilih secara bebas antara dua goroutine (paparan dan jumlah) yang tidak disekat. Walaupun pengaturcara menjangkakan paparan akan selesai dahulu dan menghantar data ke saluran sebelum jumlah selesai, ini mungkin tidak berlaku kerana sifat penjadual yang tidak menentukan.

Dalam satu kemungkinan senario pelaksanaan:

  1. utama mencipta dua goroutine untuk paparan dan jumlah.
  2. Penjadual bertukar untuk dipaparkan dengan serta-merta.
  3. paparan mencetak mesejnya dan menyekat menunggu penerima menerima data yang dihantar ke saluran .
  4. Penjadual menjalankan jumlah dan bukannya meneruskan paparan.
  5. jumlah mengira dan mencetak jumlah 10 bilion nombor.
  6. Penjadual memilih untuk menyambung semula paparan selepas jumlah selesai.
  7. paparan menghantar data ke saluran.
  8. Penjadual beralih ke utama untuk menerima data daripada saluran.
  9. utama mencetak jumlah dan keluar dari program.

Untuk menangani isu ini dan memastikan bahawa mesej "paparkan mesej pertama: hello" dicetak secara eksklusif, satu pendekatan ialah menggunakan saluran hasil untuk menerima mesej daripada paparan dan menamatkan program dengan serta-merta. Fungsi utama yang diubah suai ialah:

<code class="go">func main() {
    result := make(chan string)

    go display("hello", result)
    fmt.Println(<-result)
}</code>
Salin selepas log masuk

Atas ialah kandungan terperinci Mengapakah kod Go saya mencetak jumlah 10 bilion nombor dan bukannya hanya \'paparkan mesej pertama: hello\'?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
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!