runtime.Gosched(),用于讓出CPU時間片,讓出目前goroutine的執行權限,排程器安排其它等待的任務運作,并在下次某個時候從該位置恢複執行。這就像跑接力賽,A跑了一會碰到代碼runtime.Gosched()就把接力棒交給B了,A歇着了,B繼續跑。
runtime.Goexit(),調用此函數會立即使目前的goroutine的運作終止(終止協程),而其它的goroutine并不會受此影響。runtime.Goexit在終止目前goroutine前會先執行此goroutine的還未執行的defer語句。請注意千萬别在主函數調用runtime.Goexit,因為會引發panic。
runtime.GOMAXPROCS(),用來設定可以并行計算的CPU核數最大值,并傳回之前的值。
預設此函數的值與CPU邏輯個數相同,即有多少個goroutine并發執行,當然可以設定它,它的取值是1~256。最好在主函數在開始前設定它,因為設定它會停止目前程式的運作。
GO預設是使用一個CPU核的,除非設定runtime.GOMAXPROCS
那麼在多核環境下,什麼情況下設定runtime.GOMAXPROCS會比較好的提高速度呢?
适合于CPU密集型、并行度比較高的情景。如果是IO密集型,CPU之間的切換也會帶來性能的損失。
Gosched()代碼案例
①:沒有使用Gosched函數
package main
import (
"fmt"
)
func main() {
go func() { //子協程 //沒來的及執行主程序結束
for i := 0; i < 5; i++ {
fmt.Println("go")
}
}()
for i := 0; i < 2; i++ { //預設先執行主程序主程序執行完畢
fmt.Println("hello")
}
}
hello
hello
package main
import (
"fmt"
"runtime"
)
func main() {
go func() { //讓子協程先執行
for i := 0; i < 5; i++ {
fmt.Println("go")
}
}()
for i := 0; i < 2; i++ {
//讓出時間片,先讓别的協定執行,它執行完,再回來執行此協程
runtime.Gosched()
fmt.Println("hello")
}
}
go
go
go
go
go
hello
hello
package main
import (
"fmt"
"runtime"
)
func test() {
defer fmt.Println("ccccccccccccc")
//return //終止此函數
runtime.Goexit() //終止所在的協程
fmt.Println("dddddddddddddddddddddd")
}
func main() {
//建立建立的協程
go func() {
fmt.Println("aaaaaaaaaaaaaaaaaa")
//調用了别的函數
test()
fmt.Println("bbbbbbbbbbbbbbbbbbb")
}() //别忘了()
//特地寫一個死循環,目的不讓主協程結束
for {
}
}
aaaaaaaaaaaaaaaaaa
ccccccccccccc
package main
import (
"fmt"
"runtime"
)
func main() {
//n := runtime.GOMAXPROCS(1) //指定以1核運算
n := runtime.GOMAXPROCS(4) //指定以4核運算
fmt.Println("n = ", n)
for {
go fmt.Print(1)
fmt.Print(0)
}
}