Mengapakah coroutine utama disekat dalam kes ini, menyebabkan kebuntuan?

PHPz
Lepaskan: 2024-02-09 15:42:09
ke hadapan
582 orang telah melayarinya

Mengapakah coroutine utama disekat dalam kes ini, menyebabkan kebuntuan?

Dalam PHP, adalah perkara biasa untuk coroutine utama disekat, membawa kepada kebuntuan. Semasa pelaksanaan coroutine utama, jika ia menghadapi operasi menyekat, seperti permintaan rangkaian, operasi IO, atau menunggu keputusan coroutine lain, jika tiada kaedah pengendalian yang sesuai, kebuntuan mungkin berlaku. Dalam kes ini, coroutine utama tidak boleh terus melaksanakan, dan coroutine lain tidak boleh mendapat peluang untuk melaksanakan, dan keseluruhan program mencapai kebuntuan. Jadi mengapa coroutine utama disekat dalam kes ini, menyebabkan kebuntuan? Mari jawab ini di bawah.

Isi soalan

package main

import "fmt"

func square(numbers chan int, squares chan int) {
    for n := range numbers {
        squares <- n * n
    }
    close(squares)
}

func main() {
    numbers := make(chan int)
    squares := make(chan int)

    go square(numbers, squares)

    for i := 0; i < 10; i++ {
        numbers <- i
    }
    close(numbers)

    for s := range squares {
        fmt.Println(s)
    }
}
Salin selepas log masuk

Maksud saya, saya tahu bahawa untuk kod ini berfungsi, nombor itu hendaklah dihantar ke saluran numbers dalam goroutine yang berasingan, seperti:

go func() {
for i := 0; i < 10; i++ {
    numbers <- i
}

}
Salin selepas log masuk

Setelah berkata demikian, saya sukar untuk menjelaskan mengapa kebuntuan berlaku. Saya sangat sedar bahawa penjadual tidak menjamin perintah pelaksanaan. Walau bagaimanapun, bukankah benar bahawa kali pertama anda menghantar ke saluran numbers 通道时,主 goroutine 被阻塞,但随后调度程序可能会开始执行 square dalam gelung, goroutine utama disekat, tetapi kemudian penjadual mungkin mula melaksanakan goroutine square dan kemudian mereka berkomunikasi kembali dan seterusnya?

Penyelesaian

Sebab mengapa goroutine utama disekat ialah dalam kes ini, selepas menghantar data ke saluran petak, anda tidak membaca sebarang nilai dari saluran petak.

Apabila anda melaksanakan numbers <- i 时,你的 go square goroutine akan menerima nilai dan menghantarnya ke saluran petak. Walau bagaimanapun, pada masa yang sama, Goroutine utama anda tidak akan menerima nilai daripada saluran sqaures kerana Goroutine utama anda masih menghantar data ke saluran Numbers.

Ini bermakna coroutine utama anda tidak akan melaksanakan baris ini for s := range squares dan kemudian ia akan menyebabkan kebuntuan.

Untuk menjalankan kod ini dengan betul, anda boleh mengubah suainya seperti yang ditunjukkan di bawah.

package main

import "fmt"

func square(numbers chan int, squares chan int) {
    for n := range numbers {
        squares <- n * n
    }
    close(squares)

}

func main() {
    numbers := make(chan int)
    squares := make(chan int)

    go square(numbers, squares)

    go func() {
        for i := 0; i < 10; i++ {
            numbers <- i
        }
        close(numbers)
    }()

    for s := range squares {
        fmt.Println(s)
    }
}
Salin selepas log masuk

Atas ialah kandungan terperinci Mengapakah coroutine utama disekat dalam kes ini, menyebabkan kebuntuan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

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!