<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>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [TOC] ## **基本概念** ### **串行、并發和并行** 串行:一件事情做完再做下一件事情。 并發:同一時間段內做多件事。 并行:同一時刻做多個事情。 ### **進程、線程和協程** 進程(process):程序在操作系統中的一次執行過程,系統進行資源分配和調度的一個獨立單位。 線程(thread):操作系統基于進程開啟的輕量級進程,是操作系統調度執行的最小單位。 協程(coroutine):非操作系統而是由用戶創建和控制的用戶態線程,比線程更輕量級。 ### **并發模型** * 線程&鎖模型 * Actor模型 * CSP模型 * Fork&Join模型 Go語言中主要基于CSP(communicating sequential process)的goroutine和channel來實現,也支持使用傳統的多線程共享內存的并發方式。 ## **goroutine** Goroutine是Go語言支持并發的核心,一個goroutine會以一個很小的棧開始其生命周期,一般只需要2KB。goroutine是由Go運行時(runtime)負責調度。 Go語言中,只需要在函數或者方法前加上`go`關鍵字就可以創建一個goroutine,從而讓該函數或方法在新創建的goroutine中執行。 ``` go f() //創建一個新的goroutine 運行函數f ``` 匿名函數也支持 ``` go func() { // .... }() ``` 一個goroutine必定對應一個方法,可以創建多個goroutine去執行相同的方法。 ***** 在Go程序啟動時,會位main函數創建一個默認的goroutine。在上面的代碼中,在main函數中使用go關鍵字創建另外一個goroutine去執行hello函數,而此時main goroutine還在繼續往下執行,此時存在兩個并發執行的goroutine。當main函數結束時整個程序也就結束了。main函數退出太快,另外一個goroutine中的函數還未執行完程序就退出了。 ~~~ func hello() { fmt.Println("hello goroutine!") } func main() { go hello() fmt.Println("main goroutine done!") time.Sleep(time.Second) //讓程序停頓一會兒,就可以輸出了。 } ~~~ **為什么會先打印main函數中的fmt呢?** 因為在程序中創建goroutine執行函數需要一定的開銷,而此時main函數所在的goroutine是繼續執行的。 ### **sync.WaitGroup** `sync.WaitGroup`是實現等待一組并發操作完成的好方法。 ``` package main import ( "fmt" "sync" ) // 聲明全局等待組變量 var wg sync.WaitGroup func hello() { fmt.Println("hello") wg.Done() // 告知當前goroutine完成 } func main() { wg.Add(1) // 登記1個goroutine go hello() fmt.Println("你好") wg.Wait() // 阻塞等待登記的goroutine完成 } ``` ### **啟動多個goroutine** ``` package main import ( "fmt" "sync" ) var wg sync.WaitGroup func hello(i int) { defer wg.Done() // goroutine結束就登記-1 fmt.Println("hello", i) } func main() { for i := 0; i < 10; i++ { wg.Add(1) // 啟動一個goroutine就登記+1 go hello(i) } wg.Wait() // 等待所有登記的goroutine都結束 } ``` 多次執行上述代碼,發現打印數字的順序都不一致。這是因為10個goroutine是并發執行的,而goroutine的調度是隨機的。 ### **goroutine的調度** **動態棧:**操作系統的線程一般有固定的棧內存(通常為2MB),一個goroutine的初始棧空間很小(一般為2KB),goroutine的棧不是固定的,可以根據需要動態地增大或縮小,Go的runtime會自動為goroutine分配合適的棧空間。
                  <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>

                              哎呀哎呀视频在线观看