《Go語言編程》-並發編程

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

整理自《go語言編程》-第四章

1、並發基礎

多進程:多進程是在作業系統層面進行並發的基本模式。同時也是開銷最大的模式。在Linux平台上,很過工具鏈正是採用這種模式在工作。比如某個Web伺服器,它會有專門的進程負責網路連接埠的監聽和連結管理,還會有專門的進程負責事務和運算。這種方法的好處在於簡單、進程間互不影響,壞處是系統開銷大,因為所有的進程都是由核心管理的。
多線程:多線程在大部分作業系統上都屬於系統層面的併發模式,也是我們使用最多的最有效一種模式。目前,我們所見的幾乎所有工具鏈都會使用這種模式。它比多進程的開銷小很多,但是其開銷依舊比較大,且在高併發模式下,效率會有影響。
基於回調的非阻塞/非同步IO:這種架構的誕生實際上來源於月多線程模式的危機。在很多高並發伺服器開發實踐中,使用多線程模式會很快耗盡伺服器的記憶體和CPU資源。二這種模式通過事件驅動的方式使用非同步IO,伺服器持續運轉,且儘可能少用線程,降低開銷,它目前在Node.js中得到了很好的實踐,但是使用這種模式,編程比多線程要複雜,因為它把流程做了分割,對於問題的本身反應不夠自然。
協程:協程(coroutine)本質上一種使用者態線程,不需要作業系統來進行搶佔式調度,且在真正的實現中寄存於線程中,因此,系統開銷極小,可以有效提高線程的任務並發性,而避免多線程的缺點。使用協程的優點是編程簡單,結構清晰;缺點是需要語言的支援,如果不支援,則需要使用者在程式中自行實現調度器。

2、協程

執行體是個抽象的概念,在作業系統層面有多個概念與之對應,比如作業系統自己掌握的進程(process)、進程內的線程(thread)以及進程內的協程(coroutine,也叫輕量級線程)
多數語言在文法層面並不直接支援協程,而是通過庫的方式支援。
Go語言在語言層級支援輕量級線程,叫goroutine。

3、Goroutine

Goroutine是Go語言中的輕量級線程實現,由Go運行時(runtime)管理。
.go:關鍵字,函數調用前加go關鍵字,這次調用就會在一個新的goroutine中並發執行。當被調用的函數返回時,這個goroutine也自動結束。如果不是使用channel接收的話,這個函數的傳回值將會被丟棄。

4、並發通訊

不管是什麼平台、什麼程式設計語言並發都是一個大話題。
在工程上,有兩種最常見的並發通訊模型:共用資料和訊息。
共用資料:多個並發單元分別儲存對同一個資料的引用,實現對該資料的共用。被共用的資料可能有多種形式,比如記憶體資料區塊、磁碟檔案、網路資料等。在實際工程應用中最常見的就是共用記憶體。
Go語言社區:不要通過共用記憶體來通訊,而應該通過通訊來共用記憶體。
Go語言提供的是另一種通訊模型,即以訊息機制而非共用記憶體作為通訊方式。

5、Channel

(1)概念
Channel 是Go語言在語言層級提供的goroutine間的通訊方式。我們可以使用channel在兩個或多個goroutine之間傳遞訊息。
Channel是進程內的通訊方式,因此通過channel傳遞對象的過程和調用函數時參數
傳遞的行為比較一致,比如可以傳遞指標等。
Channel是類型相關的,一個channel只能傳遞一種類型的值。

(2)基本文法
聲明形式:
Var chanName chan ElementType
例子:var ch chan int
定義channel:
Ch := make(chan int)
向channel中寫入資料:
Ch <- value
從channel中讀取資料:
Value := <- ch

(3)select
Go語言直接在語言層級支援select關鍵字,用於處理非同步IO問題。
Select {
Case <- chan1:
//如果chan1成功讀到資料,則進行該case處理語句
Case chan2 <-1:
//如果成功向chan2寫入資料,則進行該case處理語句
Default:
//如果上面的都沒有成功,則進入default處理流程
}

(4)緩衝機制
建立一個帶緩衝區的channel:
C := make(chan int, 1024)

(5)逾時機制
在並發編程的通訊過程中,最需要處理的就是逾時問題,即向channel寫入資料時發現channel已滿,或者從channel試圖讀取資料時發現channel為空白。如果不正確處理這個問題,可能會導致整個goroutinue鎖死。
Go語言沒有提供直接的逾時處理機制,但可以利用select機制,可以解決逾時問題。

(6)channel的傳遞
注意:在go語言中channel本身也是一個原生類型,與map之類的類型地位一樣,因此channel本身在定義後也可以通過channl來傳遞。

(7)單向channel
單向channel只能用於發送或者接收資料。
從設計者的角度,所有的代碼都應該遵循“最小許可權的原則”
(8)關閉channel
使用go語言的內建函數:close(ch)
在讀取時使用多重傳回值的方式可以判斷: x, ok := <-ch

6、讓出時間片

每個goroutine中控制何時主動讓出時間片給其他goroutine,可以使用runtime包中的Gosched()函數實現。

7、同步

Go 語言套件中的sync包提供兩種鎖類型:sync.Mutex 和sync.RWMutex.

8、全域唯一性操作

Go語言提供一個Once類型來保證全域唯一性操作。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.