談談並發編程中的協程

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

高並發編程裡多線程(進程)的弊端

其實從著名的 C10K 問題的時候,就談到了高並發編程時,採用多線程(或進程)是一種不可取的解決方案,核心原因是因為線程(或進程)本質上都是作業系統的資源,每個線程需要額外佔用1M或者2M的記憶體空間,所以2G記憶體,能承受的線程數差不多隻能到1k這個量級。

而且線程的調度由作業系統調度,當線程或者進程數到達一定量級的時候,據有人實驗的結果是並發的線程數到達1k以上後,作業系統基本上就已經不堪重負,調度不過來了。

事件驅動

已知多線程已經無法解決高並發問題,所以才有了非同步IO,事件驅動等概念來解決高並發編程。很典型的就是 Node.js ,傳說中的事件驅動,其實就是在底層使用了 libuv然後通過各種回呼函數來註冊事件,當事件觸發的時候回呼函數也被觸發。使用事件驅動的方式確實能解決高並發的問題,但是因為事件驅動最費勁的就是各種喪心病狂不停的回調,在回調裡面再嵌套回調,容易陷入所謂的【回調地獄】。這也是 Node.js 最受人詬病的地方。

高並發解決方案之協程

物件導向最典型的語言是 Java ,事件驅動最典型的語言是 Node.js ,協程最典型的語言就是 golang ,當然國內程式員響馬的 fibjs 也是基於協程來進行並發的,也非常出色,只不過在生態上還是發展的太慢了。個人看來協程相對於事件驅動是一種更先進的高並發解決方案,把複雜的邏輯和非同步都封裝在底層,讓程式員在編程時感覺不到非同步存在,用響馬的話就是【用同步抒寫非同步情懷】。個人很看好協程的發展,同時也非常看好 golang 的前景,

協程也叫使用者級線程,很多人分不清楚協程和線程和進程的關係。簡單的說就是:線程和進程的調度是由作業系統來調控,而協程的調度由使用者自己調控。所以協程調度器可以在協程A即將進入阻塞IO操作,比如 socket 的 read (其實已經設定為非同步IO )之前,將該協程掛起,把當前的棧資訊 StackA 儲存下來,然後切換到協程B,等到協程A的該 IO操作返回時,再根據 StackA 切回到之前的協程A當時的狀態。

ucontext

雲風 開源過一個簡單的協程實現 cloudwu-coroutine,主要是基於 ucontext 來進行狀態的切換。

ucontext 由以下四個函數組成:

  • getcontext
  • setcontext
  • makecontext
  • swapcontext

具體含義Google一下看看例子就明白了,資料很多。說白了其實就是一種類似 goto 的編程方法,getcontext 就是將當前協程上下文獲得並存起來,setcontext 就是跳轉到某個協程上下文狀態。前者類似 label , 後者類似 goto 。makecontext 和 swapcontext 稍微再複雜一點點,但是也都是乾著環境切換的勾當。

雲風 的 cloudwu-coroutine 代碼非常乾淨漂亮,學習之餘也 fork 並修改了一份雲風的協程實現:fork-coroutine ,沒什麼高明的改進,只是對我來說更加簡單易懂。

聯繫我們

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