首页 > 后端开发 > Golang > 为什么 Go 的 select 语句需要 fmt.Print() 来终止特定的 Goroutine?

为什么 Go 的 select 语句需要 fmt.Print() 来终止特定的 Goroutine?

Susan Sarandon
发布: 2024-11-26 05:40:10
原创
870 人浏览过

Why Does a Go `select` Statement Need `fmt.Print()` to Terminate in a Specific Goroutine?

带有 select 的 goroute 不会在没有 fmt.Print() 的情况下终止

在 Go Tour 练习 #71 中,带有 select 语句的 goroute除非在默认情况下添加 fmt.Print() 语句,否则将连续执行。出现此行为的原因是存在默认语句时 select 的操作发生了变化。

如果没有默认语句,select 会阻塞,直到在任何正在监视的通道上收到消息为止。通过添加默认值,只要没有通道有消息,select就会执行默认分支。

在原始代码中,default语句创建了一个无限循环:

for {
    select {
        case todo := <-toDoList:
            ...
        case <-doneCrawling:
            ...
        default:
            if os.Args[1] == "ok" {
                fmt.Print("")
            }
            if crawling == 0 {
                goto END
            }
        }
    }
登录后复制

没有fmt。默认情况下,调度器无法调度其他goroutine,从而导致死锁。添加 fmt.Print() 可以让调度程序继续其正常功能,从而使 goroutine 能够完成。

修改代码以使用非阻塞 select 可以解决问题:

for {
    select {
        case todo := <-toDoList:
            ...
        case <-doneCrawling:
            ...
    }
    if crawling == 0 {
        break
    }
}
登录后复制

或者,可以通过设置 GOMAXPROCS=2 来使原始代码正常工作,这表明调度程序过载存在问题。

以上是为什么 Go 的 select 语句需要 fmt.Print() 来终止特定的 Goroutine?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板