英文:
GOMAXPROCS already be 2, but program still hang
问题
我已经设置了runtime.GOMAXPROCS(2)
,但是当输出一些数字时,这个程序仍然会挂起。我可以看到这个程序使用了很高的CPU(超过100%),但我不明白为什么for
循环的goroutine会导致我的程序无法工作。
我的电脑上运行的是Linux/amd64上的Go版本1.4.2,有4个CPU。
以下是代码:
package main
import "fmt"
import "runtime"
import "time"
func forever() {
for {
}
}
func show() {
for number := 1; number < 999999; number++ {
time.Sleep(1000)
fmt.Println(number)
}
}
func main() {
runtime.GOMAXPROCS(2)
go show()
go forever()
for {
time.Sleep(1000)
}
}
英文:
I already set runtime.GOMAXPROCS(2), but this program still hang when output some numbers. I can see high cpu used by this program(more than 100%), but I can't understand why the for loop goroutine can make my program not work.
go version is 1.4.2 on linux/amd64, and my pc has 4 CPUs.
here is the code:
package main
import "fmt"
import "runtime"
import "time"
func forever() {
for {
}
}
func show() {
for number := 1; number < 999999; number++ {
time.Sleep(1000)
fmt.Println(number)
}
}
func main() {
runtime.GOMAXPROCS(2)
go show()
go forever()
for {
time.Sleep(1000)
}
}
答案1
得分: 2
没有必要使用一个忙碌的循环来什么都不做,只是消耗CPU时间。它不仅会占用一个完整的操作系统线程,而且goroutine是协作调度的,它会干扰运行时的goroutine。例如,在Go1.5上,这通常会阻塞垃圾回收的停止-全局阶段(可以通过设置GOGC=off
进行测试)。
要使这个程序运行起来,你可以在for循环中插入一个调度点,但最好是完全删除它。
func forever() {
for {
runtime.Gosched()
}
}
英文:
There's no need to ever have a busy loop that does nothing except burn CPU time. Not only does it consume an entire OS thread, but goroutines are cooperatively scheduled, and it will interfere with the runtime's goroutines. For example, on Go1.5 this will usually block the stop-the-world phase of the GC, (which you can test by setting GOGC=off
).
To make this program run, you could insert a scheduling point in the for loop, but it would be better to remove it altogether.
func forever() {
for {
runtime.Gosched()
}
}
答案2
得分: 0
从代码中看,你想在Go协程中使用for循环打印数字。在这种情况下,为什么不使用通道来指示Go协程何时完成for循环,并相应地退出主函数呢?类似这样的代码:
package main
import "fmt"
import "runtime"
import "time"
func show(result chan bool) {
for number := 1; number < 999999; number++ {
time.Sleep(1000)
fmt.Println(number)
}
result <- true
}
func main() {
runtime.GOMAXPROCS(2)
result := make(chan bool)
go show(result)
<- result
}
英文:
From code, it looks like you want to print the number in for loop in go routine. In this case why not use channel to indicate when go routine is completed with for loop and accordingly exit the main function. Something like this
package main
import "fmt"
import "runtime"
import "time"
func show(result chan bool) {
for number := 1; number < 999999; number++ {
time.Sleep(1000)
fmt.Println(number)
}
result <- true
}
func main() {
runtime.GOMAXPROCS(2)
result := make(chan bool)
go show(result)
<- result
}
答案3
得分: -1
使用runtime.Gosched()
是很好的。但是在Go语言中,时间单位是纳秒,所以time.Sleep(1000)
几乎没有延迟。大多数情况下,你可以将其视为Java中的毫秒。你可以尝试使用以下代码:
time.Sleep(1000 * time.Millisecond)
英文:
It's good to use runtime.Gosched()
.
But in golang, time.Duration is in Nanoseconds, so time.Sleep(1000) is nearly no sleep. mostly you consider it as milliseconds like things in Java. you can try
time.Sleep( 1000 * time.MilliSecond )
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论