在使用通道的循环内触发通道

Trigger a channel inside the loop where the the channel is consumed

如何在消耗相同通道的循环内触发通道。下面是一个不起作用的示例代码。这是如何实现的?

https://go.dev/play/p/o5ZhNfw4IFu

package main

import (
    "context"
    "fmt"
    "time"
)

func main() {
    ch1 := make(chan struct{})
    ch2 := make(chan struct{})
    defer close(ch1)
    defer close(ch2)

    ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
    defer cancel()

    go func() {
        time.Sleep(time.Second * 1)
        ch1 <- struct{}{}
    }()

loop:
    for {
        select {
        case <-ctx.Done():
            fmt.Println("timeout")
            break loop
        case <-ch1:
            fmt.Println("ch1")
            ch2 <- struct{}{} // This here does not work!
        case <-ch2:
            fmt.Println("ch2")
        }
    }

}

1。将数据发送到 goroutine

中的 ch2
package main

import (
    "context"
    "fmt"
    "time"
)

func main() {
    ch1 := make(chan struct{})
    ch2 := make(chan struct{})
    defer close(ch1)
    defer close(ch2)

    ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
    defer cancel()

    go func() {
        time.Sleep(time.Second * 1)
        ch1 <- struct{}{}
    }()

loop:
    for {
        select {
        case <-ctx.Done():
            fmt.Println("timeout")
            break loop
        case <-ch1:
            fmt.Println("ch1")
            go func() {
                ch2 <- struct{}{}
            }()
        case <-ch2:
            fmt.Println("ch2")
        }
    }

}

2。使 ch2 缓冲

package main

import (
    "context"
    "fmt"
    "time"
)

func main() {
    ch1 := make(chan struct{})
    ch2 := make(chan struct{}, 1)
    defer close(ch1)
    defer close(ch2)

    ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
    defer cancel()

    go func() {
        time.Sleep(time.Second * 1)
        ch1 <- struct{}{}
    }()

loop:
    for {
        select {
        case <-ctx.Done():
            fmt.Println("timeout")
            break loop
        case <-ch1:
            fmt.Println("ch1")
            ch2 <- struct{}{}
        case <-ch2:
            fmt.Println("ch2")
        }
    }

}