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.
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) } }
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 } }
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?
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) } }
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!