溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

golang協程的實現方法

發布時間:2021-06-16 15:14:19 來源:億速云 閱讀:322 作者:chen 欄目:編程語言

這篇文章主要介紹“golang協程的實現方法”,在日常操作中,相信很多人在golang協程的實現方法問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”golang協程的實現方法”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

協程是應用層的線程。

應用層是相對于內核層而言,是操作系統的概念,對應的是cpu的運行級別。操作系統的核心代碼運行的ring0級別,應用程序的代碼運行在ring3級別。內核與應用層的級別設置保證了一些高權限的操作只有內核代碼能做,應用程序要使用這些功能必須通過調用操作系統的API(linux上稱為系統調用)來調用內核的代碼。這個調用會導致cpu從ring3到ring0的上下文切換,這個切換是耗費一些cpu時間的。

線程是操作系統的內核對象,多線程編程時,如果線程數過多,就會導致頻繁的上下文切換,這些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的代碼是,可以更多的關注業務邏輯的實現,更少的在這些關鍵的基礎構件上耗費太多精力。

到此,關于“golang協程的實現方法”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女