Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapakah coroutine utama disekat dalam kes ini, menyebabkan kebuntuan?

Mengapakah coroutine utama disekat dalam kes ini, menyebabkan kebuntuan?

PHPz
PHPzke hadapan
2024-02-09 15:42:09565semak imbas

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)
    }
}

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?

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 时,你的 <code>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!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam