<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                Golang 在語言層面對并發編程提供支持,一種類似協程,稱作 goroutine 的機制。 只需在函數調用語句前添加 go 關鍵字,就可創建并發執行單元。開發人員無需了解任何執行細節,調度器會自動將其安排到合適的系統線程上執行。goroutine 是一種非常輕量級的實現,可在單個進程里執行成千上萬的并發任務。 事實上,入口函數 main 就以 goroutine 運行。另有與之配套的 channel 類型,用以實現 "以通訊來共享內存" 的 CSP 模式。 ~~~ package main import "time" func main() { go func() { println("Hello, World!") }() time.Sleep(1 * time.Second) } ~~~ 輸出結果: ~~~ Hello, World! ~~~ 調度器不能保證多個 goroutine 執行次序,且進程退出時不會等待它們結束。 默認情況下,進程啟動后僅允許一個系統線程服務于 goroutine。可使用環境變量或標準庫函數 runtime.GOMAXPROCS 修改,讓調度器用多個線程實現多核并行,而不僅僅是并發。 ~~~ package main import ( "math" "sync" ) func sum(id int) { var x int64 for i := 0; i < math.MaxUint32; i++ { x += int64(i) } println(id, x) } func main() { wg := new(sync.WaitGroup) wg.Add(2) for i := 0; i < 2; i++ { go func(id int) { defer wg.Done() sum(id) }(i) } wg.Wait() } ~~~ 命令行輸入: ~~~ go build main.go time -p ./main ~~~ 輸出結果: ~~~ 0 9223372030412324865 1 9223372030412324865 real 1.92 // 程序開始到結束時間差 ( CPU 時間) user 3.80 // 用戶態所使用 CPU 時間片 (多核累加) sys 0.01 // 內核態所使用 CPU 時間片 ~~~ 命令行輸入: ~~~ GOMAXPROCS=8 time -p ./main ~~~ 輸出結果: ~~~ 1 9223372030412324865 0 9223372030412324865 real 1.89 user 3.76 // 雖然總時間差不多,但由 2 個核并行,real 時間自然少了許多。 sys 0.00 ~~~ 設置golang運行的cpu核數 單核執行如果for前面或者中間不延遲,主線程不會讓出CPU,導致異步的線程無法執行,從而無法設置flag的值,從而出現死循環。 ~~~ package main import ( "fmt" "runtime" ) var ( flag = false str string ) func foo() { flag = true str = "setup complete!" } func main() { runtime.GOMAXPROCS(1) go foo() for { if flag { break } } fmt.Println(str) } ~~~ 運行的cpu核數設置成2核 runtime.GOMAXPROCS(2) ~~~ package main import ( "fmt" "runtime" ) var ( flag = false str string ) func foo() { flag = true str = "setup complete!" } func main() { runtime.GOMAXPROCS(2) go foo() for { if flag { break } } fmt.Println(str) } ~~~ 輸出結果: ~~~ setup complete! ~~~ 調用 runtime.Goexit 將立即終止當前 goroutine 執行,調度器確保所有已注冊 defer 延遲調用被執行。 ~~~ package main import ( "runtime" "sync" ) func main() { wg := new(sync.WaitGroup) wg.Add(1) go func() { defer wg.Done() defer println("A.defer") func() { defer println("B.defer") runtime.Goexit() // 終止當前 goroutine println("B") // 不會執行 }() println("A") // 不會執行 }() wg.Wait() } ~~~ 輸出結果: ~~~ B.defer A.defer ~~~ 和協程 yield 作用類似,Gosched 讓出底層線程,將當前 goroutine 暫停,放回隊列等待下次被調度執行。 ~~~ package main import ( "runtime" "sync" ) func main() { wg := new(sync.WaitGroup) wg.Add(1) go func() { for i := 0; i < 6; i++ { println(i) runtime.Gosched() } defer wg.Done() }() for i := 0; i < 6; i++ { wg.Add(1) go func() { defer wg.Done() println("Hello, World!") }() } wg.Wait() } ~~~ 輸出結果: ~~~ Hello, World! Hello, World! 0 1 Hello, World! Hello, World! Hello, World! 2 3 4 5 Hello, World! 每次輸出結果都不一樣 ~~~ runtime.Gosched()用于讓出CPU時間片。這就像跑接力賽,A跑了一會碰到代碼runtime.Gosched()就把接力棒交給B了,A歇著了,B繼續跑。 goroutine中使用recover 應用場景,如果某個goroutine panic了,而且這個goroutine里面沒有捕獲(recover),那么整個進程就會掛掉。所以,好的習慣是每當go產生一個goroutine,就需要寫下recover。 ~~~ package main import ( "fmt" // "runtime" "time" ) func test() { defer func() { if err := recover(); err != nil { fmt.Println("panic:", err) } }() var m map[string]int m["stu"] = 100 } func calc() { for { fmt.Println("i'm calc") time.Sleep(time.Second) } } func main() { go test() for i := 0; i < 2; i++ { go calc() } time.Sleep(time.Second * 10) } ~~~ 輸出結果: ~~~ i'm calc i'm calc panic: assignment to entry in nil map i'm calc i'm calc i'm calc i'm calc i'm calc i'm calc i'm calc i'm calc i'm calc i'm calc i'm calc i'm calc i'm calc i'm calc i'm calc i'm calc i'm calc i'm calc ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看