您好,登錄后才能下訂單哦!
暫停當前goroutine,使其他goroutine先行運算。只是暫停,不是掛起,當時間片輪轉到該協程時,Gosched()后面的操作將自動恢復
package main
import (
"fmt"
)
func main() {
go output("goroutine 2")
output("goroutine 1")
}
func output(s string){
for i:=0;i<3;i++{
fmt.Println(s)
}
}
goroutine 1
goroutine 1
goroutine 1
結論:還沒等到子協程執行,主協程就已經執行完退出了,子協程將不再執行,所以打印的全部是主協程的數據。當然,實際上這個執行結果也是不確定的,只是大概率出現以上輸出,因為主協程和子協程間并沒有絕對的順序關系
package main
import (
"fmt"
"runtime"
)
func main() {
go output("goroutine 2")
runtime.Gosched()
output("goroutine 1")
}
func output(s string){
for i:=0;i<3;i++{
fmt.Println(s)
}
}
goroutine 2
goroutine 2
goroutine 2
goroutine 1
goroutine 1
goroutine 1
結論:在打印goroutine 1之前,主協程調用了runtime.Gosched()方法,暫停了主協程。子協程獲得了調度,從而先行打印了goroutine 2。主協程不是一定要等其他協程執行完才會繼續執行,而是一定時間。如果這個時間內其他協程沒有執行完,那么主協程將繼續執行,例如以下例子
package main
import (
"fmt"
"runtime"
"time"
)
func main() {
go func() {
time.Sleep(5000)
output("goroutine 2")
}()
runtime.Gosched()
output("goroutine 1")
}
func output(s string) {
for i := 0; i < 3; i++ {
fmt.Println(s)
}
}
goroutine 1
goroutine 1
goroutine 1
立即終止當前協程,不會影響其它協程,且終止前會調用此協程聲明的defer方法。由于Goexit不是panic,所以recover捕獲的error會為nil
當main方法所在主協程調用Goexit時,Goexit不會return,所以主協程將繼續等待子協程執行,當所有子協程執行完時,程序報錯deadlock
package main
import (
"fmt"
"runtime"
"time"
)
func main() {
go func(){
defer func(){
fmt.Println("defer func executed!")
fmt.Println("recovered error == ",recover())
}()
for i:=0;i<3;i++{
if i==1{
runtime.Goexit()
}
fmt.Println(i)
}
}()
time.Sleep(2*time.Second)
}
0
defer func executed!
recovered error == <nil>
設置可同時執行的邏輯Cpu數量,默認和硬件的線程數一致而不是核心數,可以通過調用GOMAXPROCS(-1)來獲取當前邏輯Cpu數
最好在main函數之前設置它,GOMAXPROCS同時也是go的環境變量之一
? 當n<1:非法數字,方法不作修改
? 當n==1:單核心,多協程并發執行,并發只是看起來是同時執行的,實際上是同一時刻只有一個協程在跑,只是由于cpu的任務調度算法,讓多個協程在效果上同時執行
? 當n>1:多核心,多協程并行執行,并行一定是并發,不同的核心同時地跑不同的協程
想要了解更多有關并發(Concurrency)和并行(Parallel)的區別,可以看看大神Rob Pike的視頻Concurrency Is Not Parallelism,里面有很詳細的講解
作者:胡金生
出處:www.aprilboy.com
版權所有,歡迎保留原文鏈接進行轉載:)
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。