睡眠程序永远不会唤醒/永远被阻止

问题描述 投票:-3回答:1

我的问题可以概括为以下代码段:

    package main

   import (
    "fmt"
    "time"
   )


func main() {

    done := make(chan int)
    done2 := make(chan int)

    go func() {
        for {
            fmt.Println("1")
            time.Sleep(time.Duration(1) * time.Second)
        }

        done <- 1
    }()



    go func() {
        for {
            fmt.Println("2")
        }
        done2 <- 1
    }()

    <- done
    <- done2

}

go例程“ 1”从没有机会再次运行。经过研究后,看起来好像是因为go例程“ 2”占用了所有CPU。

我之前在Java中做过类似的事情,线程“ 1”总是可以在大约1秒钟后唤醒。

我的问题是我如何在go中实现相同的行为?(我正在将最初用Java编写的套接字程序转移到Go中)

我也尝试过runtime.GOMAXPROCS(2),但是没有用

go goroutine
1个回答
0
投票

Go初学者使用Go例程会产生许多令人惊讶的副作用。其中更重要的一个是空无限循环的问题。

Go调度程序的工作方式,每个函数调用都应在调用开始处放置一个抢占点。这应该在您的fmt.Println("2")调用中发生,这意味着每次调用打印时,后台的调度程序都可以在任何给定时间移动正在运行的例程,增加goroutine的内存,等等。

在正常情况下,即使不是理想的编写代码,也应该足够。鉴于您已在注释中声明这不是您正在使用的实际代码,因此实际上不可能回答您的其他代码可能无法工作的原因。

[如果您有兴趣了解有关go调度程序如何工作的更多信息,我建议this文章优先考虑,以及these文章介绍较低级别的调度程序。

我也建议您浏览Tour of Go网站。尽管其中一些概念是非常基本的,但是如果您了解工具箱中的所有工具,则可以做一些非常复杂的事情。我特别推荐concurrency sectionselect statement,它们可能能够帮助您更轻松地重构程序,并且更适合您。

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