go如何终止多个for select循环嵌套

 空山新雨后,天气晚来秋。

目录

分类说明

总结


分类说明

for select循环嵌套,如何终止?上代码:

    stop := make(chan struct{})
    go func() {
        for i := 1; i < 3; i++ {
            fmt.Println("writed ", i)
            time.Sleep(time.Second * 1)
        }

        close(stop)
        fmt.Println("stop closed.")
    }()

    go func() {
    stop1:
        for {
            select {
            case <-stop:
                fmt.Println("recv 1")
                break stop1
            default:

                fmt.Println("A 1 default...")

                for {
                    select {
                    case <-stop:
                        fmt.Println("recv 2")
                        break stop1
                    default:
                        fmt.Println("A 2 default...")
                        time.Sleep(time.Second * 1)
                    }
                }
            }
        }

        fmt.Println("A 结束")
    }()

    fmt.Println("已关闭", stop == nil)
    for i := 1; i < 10; i++ {
        time.Sleep(time.Second * 1)
        fmt.Println("ch==nil: ", stop == nil, "   num=", runtime.NumGoroutine())
    }

如上,内外均监听了stop,内层接受到信号后直接终止stop1,全流程正常结束。效果如下:
speed running:

已关闭 false
A 1 default...
A 2 default...
writed  1
A 2 default...
writed  2
ch==nil:  false    num= 3
ch==nil:  false    num= 3
A 2 default...
stop closed.
recv 2
A 结束
ch==nil:  false    num= 1
ch==nil:  false    num= 1
ch==nil:  false    num= 1
ch==nil:  false    num= 1
ch==nil:  false    num= 1
ch==nil:  false    num= 1
ch==nil:  false    num= 1

换成先终止内层也可:

    stop := make(chan struct{})
    go func() {
        for i := 1; i < 3; i++ {

            fmt.Println("writed ", i)
            time.Sleep(time.Second * 1)
        }

        close(stop)
        fmt.Println("stop closed.")
    }()

    go func() {
    stop1:
        for {
            select {
            case <-stop: // 这里也可收到信号
                fmt.Println("recv 1")
                break stop1
            default:

                fmt.Println("A 1 default...")
            stop2:
                for {
                    select {
                    case <-stop: // 这里可收到信号
                        fmt.Println("recv 2")
                        break stop2 // 换成终止内层
                    default:
                        fmt.Println("A 2 default...")
                        time.Sleep(time.Second * 1)
                    }
                }

                fmt.Println("A 2 stop...")
            }
        }

        fmt.Println("A 结束")
    }()

    fmt.Println("已关闭", stop == nil)
    for i := 1; i < 10; i++ {
        time.Sleep(time.Second * 1)
        fmt.Println("ch==nil: ", stop == nil, "   num=", runtime.NumGoroutine())
    }

如上代码,在内层先终止自己的逻辑stop2,外层也随之终止,正常结束。效果如下:


speed running:

已关闭 false
writed  1
A 1 default...
A 2 default...
writed  2
ch==nil:  false    num= 3
A 2 default...
A 2 default...
ch==nil:  false    num= 3
stop closed.
recv 2
A 2 stop...
recv 1
A 结束
ch==nil:  false    num= 2
ch==nil:  false    num= 1
ch==nil:  false    num= 1
ch==nil:  false    num= 1
ch==nil:  false    num= 1
ch==nil:  false    num= 1
ch==nil:  false    num= 1

如果不是基于关闭操作而是写入呢,内层和外层都能收到吗? 答:只会接收一次。

stop := make(chan struct{})
    go func() {
        for i := 1; i < 3; i++ {
            //ch <- i
            fmt.Println("writed ", i)
            time.Sleep(time.Second * 1)
        }

        stop <- struct{}{}// close(stop)
        fmt.Println("stop writed.")
    }()

    go func() {
    stop1:
        for {
            select {
            case <-stop: // 这里未收到信号
                fmt.Println("recv 1")
                break stop1
            //case data := <-ch:
            //    fmt.Println("A  data=", data)
            default:

                fmt.Println("A 1 default...")
            stop2:
                for {
                    select {
                    case <-stop: // 这里可收到信号
                        fmt.Println("recv 2")
                        break stop2 // 换成终止内层
                    default:
                        fmt.Println("A 2 default...")
                        time.Sleep(time.Second * 1)
                    }
                }

                fmt.Println("A 2 stop...")
            }
        }

        fmt.Println("A 结束")
    }()

    fmt.Println("stop == nil: ", stop == nil)
    for i := 1; i < 10; i++ {
        time.Sleep(time.Second * 1)
        fmt.Println("ch==nil: ", stop == nil, "   num=", runtime.NumGoroutine())
    }

    close(stop)
    fmt.Println("stop已关闭, ", stop == nil)

speed running:

stop == nil:  false
writed  1
A 1 default...
A 2 default...
A 2 default...
writed  2
ch==nil:  false    num= 3
recv 2
A 2 stop...
A 1 default...
A 2 default...
stop writed.
ch==nil:  false    num= 3
ch==nil:  false    num= 2
A 2 default...
A 2 default...
ch==nil:  false    num= 2
ch==nil:  false    num= 2
A 2 default...
A 2 default...
ch==nil:  false    num= 2
A 2 default...
ch==nil:  false    num= 2
ch==nil:  false    num= 2
A 2 default...
A 2 default...
ch==nil:  false    num= 2
stop已关闭,  false

总结

触发条件需要全部结束时,直接终止最外层for select 即可达到其下嵌套的所有该循环的目的。

相关推荐

  1. go如何终止for select循环嵌套

    2024-01-13 21:26:03       53 阅读
  2. 如何Go中构建For循环

    2024-01-13 21:26:03       58 阅读
  3. 如何解决Go包中循环依赖】

    2024-01-13 21:26:03       40 阅读
  4. c# 循环如何跳出

    2024-01-13 21:26:03       56 阅读
  5. Go语言中如何处理goroutine和循环变量

    2024-01-13 21:26:03       38 阅读
  6. mybatis-plus循环处理条件的 or 查询

    2024-01-13 21:26:03       47 阅读
  7. 列表循环el-form-item并校验

    2024-01-13 21:26:03       41 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-13 21:26:03       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-13 21:26:03       106 阅读
  3. 在Django里面运行非项目文件

    2024-01-13 21:26:03       87 阅读
  4. Python语言-面向对象

    2024-01-13 21:26:03       96 阅读

热门阅读

  1. Redis面试题12

    2024-01-13 21:26:03       54 阅读
  2. 达梦数据实时同步工具DMHS常见故障处理

    2024-01-13 21:26:03       55 阅读
  3. Union-Find

    2024-01-13 21:26:03       62 阅读
  4. 【数模百科】2004-2023年美赛获奖论文下载

    2024-01-13 21:26:03       63 阅读
  5. 麒麟系统编写桌面点击可执行文件

    2024-01-13 21:26:03       94 阅读
  6. 作业-去重复统计(2)

    2024-01-13 21:26:03       51 阅读
  7. 三国杀移动版武将台词大全-蜀

    2024-01-13 21:26:03       62 阅读
  8. Linux文件和目录管理命令----chmod命令

    2024-01-13 21:26:03       61 阅读
  9. 补充前端访问静态资源的一个错误

    2024-01-13 21:26:03       64 阅读