建立一個goroutine大概2KB的棧空間,新建立的線程會佔用1MB的內存空間。併發
線程須要從操做系統裏請求資源並在用完以後釋放回去,所以建立和銷燬線程的開銷很是大。
goroutine的建立和銷燬是由運行環境(runtime)完成的,這些操做的開銷就比較小。函數
當切換一個線程的時候,調度器須要保存/恢復全部的寄存器。這包括16個通用寄存器,程序指針(program counter),棧指針(stack pointer),段寄存器(segment registers)和16個XMM寄存器,浮點協處理器狀態,16個AVX寄存器,全部的特殊模塊寄存器(MSR)等。當在線程間快速切換的時候這些開銷就變得很是大了
Goroutine的調度是協同合做式的(cooperatively)。當切換goroutine的時候,調度器只須要保存和恢復三個寄存器 - 程序指針,棧指針和DX。切換的開銷就小多了。oop
並行:是讓不一樣的代碼片斷同時在不一樣的物理處理器上執行,並行的關鍵是同時作不少事情。
併發:指同時管理不少事情,這些事情可能只作了一半就被暫停去作別的事情了,goroutine是一種併發機制。操作系統
package main import "fmt" func main() { var i = 3 go func(a int) { fmt.Println(a) fmt.Println("1") }(i) fmt.Println("2") }
package main import ( "runtime" "sync" "fmt" ) func main() { // 分配一個邏輯處理器給調度器使用 runtime.GOMAXPROCS(1) // wg用來等待程序完成,計數加2,表示要等待兩個goroutine var wg sync.WaitGroup wg.Add(2) fmt.Println("Start Goroutines") // 聲明一個匿名函數,並建立一個goroutine go func() { // 延時調用,在函數退出時調用done來通知main函數工做已經完成 defer wg.Done() // 顯示字母表三次 for count := 0; count < 3; count ++ { for char := 'a'; char < 'a' + 26 ; char ++ { fmt.Printf("%c ", char) } } }() go func() { defer wg.Done() for count := 0; count < 3; count ++ { for char := 'A'; char < 'A' + 26 ; char ++ { //time.Sleep(time.Millisecond) fmt.Printf("%c ", char) } } }() fmt.Println("Wating To Finish") wg.Wait() fmt.Println("\nTerminating Program") }