Go 睡眠程序永远不会醒来/永远被阻塞
我的问题可以总结为以下代码段:Go 睡眠程序永远不会醒来/永远被阻塞,go,goroutine,Go,Goroutine,我的问题可以总结为以下代码段: 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
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
}
在那里,围棋1再也没有机会跑了。在做了一些研究之后,看起来是因为go例程2占用了所有的CPU
我以前在java中也做过类似的事情,线程1总是可以在大约1秒后醒来
我的问题是如何在go中实现相同的行为?我正在将一个最初用Java编写的socket程序传输到go
我也尝试过runtime.GOMAXPROCS2,但没有成功对于新手来说,Go例程可能会有很多令人惊讶的副作用。其中一个更重要的问题是空无限循环的问题 按照Go调度器的工作方式,每个函数调用都应该在调用的开头放置一个抢占点。这应该发生在您的fmt.Println2调用中,这意味着每次调用print时,后台的调度程序都能够在任何给定时间移动正在运行的例程,增加goroutine的内存,等等 在正常情况下,即使它不是理想的编写代码,这应该足够了。考虑到您在评论中指出这不是您正在使用的实际代码,因此不可能真正回答为什么您的其他代码可能不起作用 如果您有兴趣了解更多关于go调度器如何工作的信息,我建议您阅读有关抢占的文章,以及在较低级别上介绍调度器的文章
我还建议大家浏览一下这个网站。虽然其中一些概念相当基本,但如果您了解工具箱中的所有工具,则可以执行一些非常复杂的操作。我特别推荐,和,它可能会帮助您更容易地重构程序,并且以更适合的方式进行重构 goroutine不是线程。在当前版本中,它们不是可抢占的。这样的紧密循环不会让其他goroutine运行。顺便说一句,在循环中使用fmt.Println不会阻止goroutine调度程序运行其他goroutine,因为这涉及IO操作。因此,在您的示例中,所有的goroutine都被安排好了,但是您的示例代码有无止境的循环,它们永远不会结束。请注意,Go中的socket程序无论如何都不应该有这样的代码,如果goroutine需要协调,那么时间就是答案。睡眠永远不是答案。最好说明实际的问题是什么。@user9607441:网络操作被阻塞了,所以除了消息之间的间隔之外,我看不出任何需要睡眠的原因。你描述的场景与你上面写的非常不同。无限循环本身不是问题,每个网络服务器定义都有一个循环;问题是,虽然网络操作只有在有数据时才会运行,但Println会立即继续。一般来说,如果您在某些代码上遇到问题,请发布这些代码,而不是一个模糊不清的类似示例。这个例子是如此精心设计,它保证与您在Go中使用socket编程时遇到的任何问题无关。