如果有定时器,select中如何选择通道?

问题描述 投票:0回答:1

我想了解选择和计时器是如何工作的。我有一个简单的例子

import (
    "fmt"
    "time"
)

func main() {
    ch1 := make(chan int, 10)
    for i := 0; i < 5; i++ {
        ch1 <- i
    }
    timer := time.NewTimer(1 * time.Second)
    close(ch1)
    for i := 0; i < 10; i++ {
        select {
        case data, ok := <-ch1:              //1
            if !ok {
                fmt.Println("Data channel close", data)
                return
            }
            fmt.Println("Not close", data)
        case <-timer.C:                      //2
            fmt.Println("Timer triggered")
            timer.Reset(1 * time.Second)
        }
        time.Sleep(2 * time.Second)
    }

}

我预计,因为ch1通道中有数据,所以它会一直工作//1。但碰巧只有 //2 有效

Not close 0
Timer triggered
Timer triggered
Timer triggered
Timer triggered
Timer triggered
Timer triggered
Not close 1
Not close 2
Timer triggered

Program exited.

如何了解哪种情况可行?

go channel
1个回答
0
投票
package main

import (
    "fmt"
    "time"
)

func main() {
    // Create a buffered channel of type int with a buffer size of 10.
    ch1 := make(chan int, 10)

    // Send integers 0 to 4 into the channel.
    for i := 0; i < 5; i++ {
        ch1 <- i
    }

    // Create a timer that will fire after 1 second.
    timer := time.NewTimer(1 * time.Second)

    // Close the channel to indicate that no more values will be sent through it.
    close(ch1)

    // Enter a loop that iterates 10 times.
    for i := 0; i < 10; i++ {
        // Use the select statement to handle channel receive and timer cases.
        select {
        case data, ok := <-ch1:
            // Case 1: If there is data available in the channel ch1.
            if !ok {
                // The channel is closed, and no more data can be received.
                fmt.Println("Data channel close", data)
                return // Exit the program.
            }
            // Print the received data if the channel is not closed.
            fmt.Println("Not close", data)

        case <-timer.C:
            // Case 2: The timer has triggered (1 second has passed).
            fmt.Println("Timer triggered")
            timer.Reset(1 * time.Second) // Reset the timer to trigger again after 1 second.
        }

        // Introduce a 2-second delay before the next iteration of the loop.
        time.Sleep(2 * time.Second)
    }
}

我对代码进行了注释以便更好地理解。

© www.soinside.com 2019 - 2024. All rights reserved.