goroutine 不再被调度
goroutine is not be scheduled again
我正在学习 golang。我有一个 goroutine 来打印变量 i
,然后我写了一个死循环。但是当var i
up to 491519(or some other value)
时,终端没有任何输出。看起来print var i
的goroutine 不再被调度,CPU 输出491519
之后一直执行死循环。谁能告诉我原因?
谢谢。
我的代码:
package main
import (
"fmt"
"runtime"
)
func main() {
go func() {
i := 1
for {
fmt.Println(i)
i = i + 1
}
}()
runtime.GOMAXPROCS(4)
for {
}
}
我想补充一点:
当我在最后一个死循环中添加 fmt.Println("ABC")
时,终端上永远交替输出 ABC
或 i
。
我的版本:go version go1.9.1 darwin/amd64
死循环将使用大量 CPU 并可能导致调度程序问题。如果你想阻塞一个 goroutine,从一个从未写入的通道中读取会更有效:
ch := make(chan struct{})
<-ch
或者更好的是,设置一个通道来等待关闭应用程序的信号:
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt)
<-stop
也不需要设置GOMAXPROCS
.
Goroutines 由 Go 运行时调度,因此与操作系统完成的进程调度相比存在一些限制。操作系统可以通过定时中断抢占进程,Go运行时不能抢占goroutines。
Go runtime 在 goroutine
时调度另一个 goroutine
- 进行通道操作(这包括select语句,甚至为空)
- 进行系统调用
- 显式调用 runtime.Gosched
设置 GOMAXPROCS 没有多大帮助。看看下面的程序。它将使用所有处理器并将保持在紧密的繁忙循环中。
func runForever() {
for {
}
}
func main() {
for i := 0; i < runtime.GOMAXPROCS(-1); i++ {
go runForever()
}
time.Sleep(time.Second)
}
有几种修复程序的方法:
go func() {
for i:= 1; true; i++ {
fmt.Println(i)
}
}()
for {
runtime.Gosched()
}
或
go func() {
for i:= 1; true; i++ {
fmt.Println(i)
}
}()
select {
}
我正在学习 golang。我有一个 goroutine 来打印变量 i
,然后我写了一个死循环。但是当var i
up to 491519(or some other value)
时,终端没有任何输出。看起来print var i
的goroutine 不再被调度,CPU 输出491519
之后一直执行死循环。谁能告诉我原因?
谢谢。
我的代码:
package main
import (
"fmt"
"runtime"
)
func main() {
go func() {
i := 1
for {
fmt.Println(i)
i = i + 1
}
}()
runtime.GOMAXPROCS(4)
for {
}
}
我想补充一点:
当我在最后一个死循环中添加 fmt.Println("ABC")
时,终端上永远交替输出 ABC
或 i
。
我的版本:go version go1.9.1 darwin/amd64
死循环将使用大量 CPU 并可能导致调度程序问题。如果你想阻塞一个 goroutine,从一个从未写入的通道中读取会更有效:
ch := make(chan struct{})
<-ch
或者更好的是,设置一个通道来等待关闭应用程序的信号:
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt)
<-stop
也不需要设置GOMAXPROCS
.
Goroutines 由 Go 运行时调度,因此与操作系统完成的进程调度相比存在一些限制。操作系统可以通过定时中断抢占进程,Go运行时不能抢占goroutines。
Go runtime 在 goroutine
时调度另一个 goroutine- 进行通道操作(这包括select语句,甚至为空)
- 进行系统调用
- 显式调用 runtime.Gosched
设置 GOMAXPROCS 没有多大帮助。看看下面的程序。它将使用所有处理器并将保持在紧密的繁忙循环中。
func runForever() {
for {
}
}
func main() {
for i := 0; i < runtime.GOMAXPROCS(-1); i++ {
go runForever()
}
time.Sleep(time.Second)
}
有几种修复程序的方法:
go func() {
for i:= 1; true; i++ {
fmt.Println(i)
}
}()
for {
runtime.Gosched()
}
或
go func() {
for i:= 1; true; i++ {
fmt.Println(i)
}
}()
select {
}