這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
Go語言:簡介(二)
對Go語言瞭解前,我們先來補一些基本概念
基本概念
一個並發程式可以在一個處理器或者核心上使用多個線程來執行任務,但是只有同一個程式在某個時間點同時運行在多核或者多處理器上才是真正的並行。
並發程式可以是並行的,也可以不是。
使用多線程的應用難以做到準確,最主要的問題是記憶體中的資料共用,它們會被多線程以無法預知的方式進行操作,導致一些無法重現或者隨機的結果。
使用多線程需要在意同步問題,可能出現死結,線程環境切換帶來的開銷
利用多核CPU,將計算分發到各個子進程,將大量的計算分解掉,然後再通過進程間的事件訊息來傳遞結果。
什麼是協程
1.協程與線程關係
在協程和作業系統線程之間並無一對一的關係:協程是根據一個或多個線程的可用性,映射(多工,執行於)在他們之上的;協程調度器在 Go 運行時很好的完成了這個工作。
2.協程實現
當系統調用(比如等待 I/O)阻塞協程時,其他協程會繼續在其他線程上工作。**協程 的設計隱藏了許多線程建立和管理方面的複雜工作。**
3.協程代價
協程是輕量的,比線程更輕。它們痕迹非常不明顯(使用少量的記憶體和資源):使用 4K 的棧記憶體就可以在堆中建立它們。因為建立非常廉價,必要的時候可以輕鬆建立並運行大量的協程(在同一個地址空間中 100,000 個連續的協程)。
什麼是通道
通道只能傳輸一種類型的資料,比如 chan int 或者 chan string,所有的類型都可以用於通道,空介面 interface{} 也可以。甚至可以(有時非常有用)建立通道的通道。
通道實際上是類型化訊息的隊列:使資料得以傳輸。它是先進先出(FIFO)結構的所以可以保證發送給他們的元素的順序(有些人知道,通道可以比作 Unix shells 中的雙向管道(tw-way pipe))。
預設情況下,通訊是同步且無緩衝的:在有接受者接收資料之前,發送不會結束。可以想象一個無緩衝的通道在沒有空間來儲存資料的時候:必須要一個接收者準備好接收通道的資料然後寄件者可以直接把資料發送給接收者。所以通道的發送/接收操作在對方準備好之前是阻塞的。
例子:
package mainimport ( "fmt" "time")func main() { ch := make(chan string) go sendData(ch) go getData(ch) time.Sleep(1e9)}func sendData(ch chan string) { ch <- "Washington" ch <- "Tripoli" ch <- "London" ch <- "Beijing" ch <- "Tokio"}func getData(ch chan string) { var input string // time.Sleep(1e9) for { input = <-ch fmt.Printf("%s ", input) }}
輸出:
Washington Tripoli London Beijing Tokio