GoLang之並發並行與goroutine的思考

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

2015-04-14 wcdj


GoLang之Concurrency再討論一文討論過並發的幾個問題,分別如下:

1,goroutine是否並發的問題
2,goroutine非並發安全性問題
3,並發情況下的原子操作問題

本文在上述討論的基礎上,進一步對goroutine的調度機制,以及並發的實現原理進行討論。


0 goroutine 輕量的調度單位

程式員使用goroutine可以快速地開發一個並發(可能非並行)執行的程式。goroutine是協程(coroutine,輕量級進程,Light Weight Process)的一種實現,Linux POSIX C也提供了coroutine系統調用。協程(輕量級進程),就是在使用者空間實現調度,比線程更輕量的執行單元。協程的調度不是搶佔式的,這就意味著同一線程內的協程只有主動放棄CPU,調度器才會將另外一個等待的協程調度進來然後執行。goroutine在Go語言的運行時環境(runtime)中實現,在使用者空間內被調度於一個或多個線程之間(而非限定在一個線程中)。當一個goroutine調用了某個可能阻塞的標準庫函數之後,這個goroutine則會被運行時環境暫停,另一個準備好的goroutine則被調度進來然後開始執行。

原則上,Go語言運行時環境中的調度器與作業系統的調度器並沒有太大區別,都是在某個事件發生時,將最小調度單位暫停或啟動,但goroutine的調度在使用者空間內執行,因此調度速度更快,並且可以支援大量並發的goroutine同時運行。

Go語言是一個完全編譯型的語言(靜態語言),它的代碼被直接編譯成本地機器碼執行,因此不存在中間的解譯器或者虛擬機器。要實現goroutine運行時的功能,Go語言是利用運行時環境來完成的。Go的程式在連結時,都會被加入一套運行時環境。這套環境類似於一個靜態庫,包含來Go語言中規定的一些運行時特性,例如,記憶體回收,goroutine調度等。在Go語言標準庫中,在每個可能產生阻塞的函數中,都會最終通知運行時環境中的調度器,讓調度器將當前的goroutine暫停,這樣的設計可以極大地簡化並發(可能非並行)程式的開發。


1 goroutine與丟失的select/poll/epoll等非阻塞調用

在Go語言中,是否提供了類似C語言中select/poll/epoll函數?如何讓一個網路連接使用非阻塞I/O?怎麼對網路連接進行非同步讀寫?

這幾個問題回答是:Go的網路程式不使用非同步作業,一切操作都是同步的,每個goroutine處理一個串連。

在Go代碼層面,開發人員看到的是使用goroutine來進行阻塞式讀寫,而在Go的內部實現中,則是利用非同步作業,通過對goroutine的調度來完成對事件的處理。作為最小的調度單位,goroutine之間是並發(可能非並行)執行的。






聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.