日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

golang 学习 (八)协程

發布時間:2025/3/21 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 golang 学习 (八)协程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一:?進程、線程 和 協程 之間概念的區別:

? ? ? ?對于?進程、線程,都是有內核進行調度,有 CPU 時間片的概念,進行?搶占式調度(有多種調度算法)

  ? ?(補充: 搶占式調度與非搶占(輪詢任務調度)區別在于搶占式調度可以因為優先級高的任務搶占cpu,而輪詢的不能)

  對于?協程(用戶級線程),這是對內核透明的,也就是系統并不知道有協程的存在,是完全由用戶自己的程序進行調度的,因為是由用戶程序自己控制,那么就很難像搶占式調度那樣做到強制的 CPU 控制權切換到其他進程/線程,通常只能進行?協作式調度,需要協程自己主動把控制權轉讓出去之后,其他協程才能被執行到。

 goroutine 和協程區別:

  本質上,goroutine 就是協程。?不同的是,Golang 在 runtime、系統調用等多方面對 goroutine 調度進行了封裝和處理,當遇到長時間執行或者進行系統調用時,會主動把當前 goroutine 的CPU (P) 轉讓出去,讓其他 goroutine 能被調度并執行,也就是 Golang 從語言層面支持了協程。Golang 的一大特色就是從語言層面原生支持協程,在函數或者方法前面加 go關鍵字就可創建一個協程。

 其他方面的比較

  1. 內存消耗方面

    每個 goroutine (協程) 默認占用內存遠比 Java 、C 的線程少。
    goroutine:2KB?
    線程:8MB

  2. 線程和 goroutine 切換調度開銷方面

    線程/goroutine 切換開銷方面,goroutine 遠比線程小
    線程:涉及模式切換(從用戶態切換到內核態)、16個寄存器、PC、SP...等寄存器的刷新等。
    goroutine:只有三個寄存器的值修改 - PC / SP / DX.

二:?進程、線程 和 協程 之間概念的區別:?

  線程是操作系統的內核對象,多線程編程時,如果線程數過多,就會導致頻繁的上下文切換,這些 cpu 時間是一個額外的耗費。所以在一些高并發的網絡服務器編程中,使用一個線程服務一個 socket 連接是很不明智的。于是操作系統提供了基于事件模式的異步編程模型。用少量的線程來服務大量的網絡連接和I/O操作。但是采用異步和基于事件的編程模型,復雜化了程序代碼的編寫,非常容易出錯。因為線程穿插,也提高排查錯誤的難度。

?  協程,是在應用層模擬的線程,他避免了上下文切換的額外耗費,兼顧了多線程的優點。簡化了高并發程序的復雜度。

  舉個例子,一個高并發的網絡服務器,每一個socket連接進來,服務器用一個協程來對他進行服務。代碼非常清晰。而且兼顧了性能。

那么,協程是怎么實現的呢?

  他和線程的原理是一樣的,當 a線程 切換到 b線程 的時候,需要將 a線程 的相關執行進度壓入棧,然后將 b線程 的執行進度出棧,進入 b線程 的執行序列。協程只不過是在 應用層 實現這一點。但是,協程并不是由操作系統調度的,而且應用程序也沒有能力和權限執行 cpu 調度。怎么解決這個問題?

  答案是,協程是基于線程的。內部實現上,維護了一組數據結構和 n 個線程,真正的執行還是線程,協程執行的代碼被扔進一個待執行隊列中,由這 n 個線程從隊列中拉出來執行。這就解決了協程的執行問題。那么協程是怎么切換的呢?答案是:golang 對各種 io函數 進行了封裝,這些封裝的函數提供給應用程序使用,而其內部調用了操作系統的異步 io函數,當這些異步函數返回 busy 或 bloking 時,golang 利用這個時機將現有的執行序列壓棧,讓線程去拉另外一個協程的代碼來執行,基本原理就是這樣,利用并封裝了操作系統的異步函數。包括 linux 的 epoll、select 和 windows 的 iocp、event 等。

?  由于golang是從編譯器和語言基礎庫多個層面對協程做了實現,所以,golang的協程是目前各類有協程概念的語言中實現的最完整和成熟的。十萬個協程同時運行也毫無壓力。關鍵我們不會這么寫代碼。但是總體而言,程序員可以在編寫 golang 代碼的時候,可以更多的關注業務邏輯的實現,更少的在這些關鍵的基礎構件上耗費太多精力。

  但是由于協程是非搶占式的調度,無法實現公平的任務調用。

  盡管,在任務調度上,協程是弱于線程的。但是在資源消耗上,協程則是極低的。一個線程的內存在?MB?級別,而協程只需要?KB?級別。而且線程的調度需要內核態與用戶的頻繁切入切出,資源消耗較高。

  我們把協程的基本特點歸納為:

1 2 1. 協程調度機制無法實現公平調度 2. 協程的資源開銷是非常低的,一臺普通的服務器就可以支持百萬協程。

?  那么,近幾年為何協程的概念可以大熱。我認為一個特殊的場景使得協程能夠廣泛的發揮其優勢,并且屏蔽掉了劣勢 --> 網絡編程。與一般的計算機程序相比,網絡編程有其獨有的特點。

1 2 3 1. 高并發(每秒鐘上千數萬的單機訪問量) 2. Request/Response。程序生命期端(毫秒,秒級) 3. 高IO,低計算(連接數據庫,請求API)。

?

轉載于:https://www.cnblogs.com/liufei1983/p/11191970.html

總結

以上是生活随笔為你收集整理的golang 学习 (八)协程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。