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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

关于C10K、异步回调、协程、同步阻塞

發布時間:2023/12/31 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于C10K、异步回调、协程、同步阻塞 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

最近到處在爭論這些話題,發現很多人對一些基礎的常識并不了解,在此發表一文做一下解釋。此文未必能解答所有問題,各位能有一個大致的了解就好。

C10K的由來

大家都知道互聯網的基礎就是網絡通信,早期的互聯網可以說是一個小群體的集合。互聯網還不夠普及,用戶也不多。一臺服務器同時在線100個用戶估計在當時已經算是大型應用了。所以并不存在什么C10K的難題。互聯網的爆發期應該是在www網站,瀏覽器,雅虎出現后。最早的互聯網稱之為Web1.0,互聯網大部分的使用場景是下載一個Html頁面,用戶在瀏覽器中查看網頁上的信息。這個時期也不存在C10K問題。

Web2.0時代到來后就不同了,1方面是普及率大大提高了,用戶群體幾何倍增長。2是互聯網不再是單純的瀏覽萬維網網頁,逐漸開始進行交互,而且應用程序的邏輯也變的更復雜,從簡單的表單提交,到即時通信和在線實時互動。C10K的問題才體現出來了。每一個用戶都必須與服務器保持TCP連接才能進行實時的數據交互。Facebook這樣的網站同一時間的并發TCP連接可能會過億。

騰訊QQ也是有C10K問題的,只不過他們是用了UDP這種原始的包交換協議來實現的,繞開了這個難題。當然過程肯定是痛苦的。如果當時有epoll技術,他們肯定會用TCP。后來的手機QQ,微信都采用TCP協議。

這時候問題就來了,最初的服務器都是基于進程/線程模型的,新到來一個TCP連接,就需要分配1個進程(或者線程)。而進程又是操作系統最昂貴的資源,一臺機器無法創建很多進程。如果是C10K就要創建1萬個進程,那么操作系統是無法承受的。如果是采用分布式系統,維持1億用戶在線需要10萬臺服務器,成本巨大,也只有Facebook,Google,雅虎才有財力購買如此多的服務器。這就是C10K問題的本質。

實際上當時也有異步模式,如:select/poll模型,這些技術都有一定的缺點,如selelct最大不能超過1024,poll沒有限制,但每次收到數據需要遍歷每一個連接查看哪個連接有數據請求。

Epoll異步非阻塞

既然有了C10K問題,程序員們就開始行動去解決它。于是FreeBSD推出了kqueue,Linux推出了epoll,Windows推出了IOCP。這些操作系統提供的功能就是為了解決C10K問題。因為Linux是互聯網企業中使用率最高的操作系統,Epoll就成為C10K killer、高并發、高性能、異步非阻塞這些技術的代名詞了。

epoll技術的編程模型就是異步非阻塞回調,也可以叫做Reactor,事件驅動,事件輪循(EventLoop)。Epoll就是為了解決C10K問題而生。使用Epoll技術,使得小公司也可以玩高并發。不需要購買很多服務器,有幾臺服務器就可以服務大量用戶。Nginx,libevent,node.js這些就是Epoll時代的產物。

C100K,C1M,C10M,C100M …

C10K問題解決后,程序員又提出了更高的挑戰,也就是最近在火熱爭論的C100K,C1M等。Epoll既然能解決C10K,解決什么C100K,C1M也是可以的。只不過這個已經沒有意義了。一個公司有1億用戶難道他買不起1萬臺服務器嘛。WhatsApp有2億用戶,賣了150億美元。1萬臺服務器最多花費5000萬美元。

看到阿里技術保障部的人也在談C10K話題,我要補充一下,搞路由器、交換機、網關、防火墻之類基礎網絡設備的人,就不要參與C10K話題了。我們說的是應用層程序。

協程,coroutine

當程序員還沉浸在解決C10K問題帶來的成就感時,一個新的問題被拋出了。異步嵌套回調太TM難寫了。尤其是Node.js層層回調,縮進了幾十層,要把程序員逼瘋了。于是一個新的技術被提出來了,那就是協程(coroutine)。這個技術本質上也是異步非阻塞技術,它是將事件回調進行了包裝,讓程序員看不到里面的事件循環。程序員就像寫阻塞代碼一樣簡單。比如調用 client->recv() 等待接收數據時,就像阻塞代碼一樣寫。實際上是底層庫在執行recv時悄悄保存了一個狀態,比如代碼行數,局部變量的值。然后就跳回到EventLoop中了。什么時候真的數據到來時,它再把剛才保存的代碼行數,局部變量值取出來,又開始繼續執行。

這個就像時間禁止的游戲一樣,國王對巫師說“我必須馬上得到寶物,不然就砍了你的腦袋”,巫師念了一句時間停止的咒語,直到過了1年后勇士們才把寶物送來。這時候巫師解開咒語,把寶物交給國王。這里國王就可以理解成協程,他根本沒感覺到時間停止,在他停止到醒來期間發生了什么他不知道,也不關心。

這就是協程的本質。協程是異步非阻塞的另外一種展現形式。Golang,Erlang,Lua協程都是這個模型。

同步阻塞

再回到同步阻塞這個話題,不知道大家看完協程是否感覺得到,實際上協程和同步阻塞是一樣的。答案是的。所以協程也叫做用戶態進/用戶態線程。區別就在于進程/線程是操作系統充當了EventLoop調度,而協程是自己用Epoll進行調度。

協程的優點是它比系統線程開銷小,缺點是如果其中一個協程中有密集計算,其他的協程就不運行了。操作系統進程的缺點是開銷大,優點是無論代碼怎么寫,所有進程都可以并發運行。

Erlang解決了協程密集計算的問題,它基于自行開發VM,并不執行機器碼。即使存在密集計算的場景,VM發現某個協程執行時間過長,也可以進行中止切換。Golang由于是直接執行機器碼的,所以無法解決此問題。所以Golang要求用戶必須在密集計算的代碼中,自行Yield。

實際上同步阻塞程序的性能并不差,它的效率很高,不會浪費資源。當進程發生阻塞后,操作系統會將它掛起,不會分配CPU。直到數據到達才會分配CPU。多進程只是開多了之后副作用太大,因為進程多了互相切換有開銷。所以如果一個服務器程序只有1000左右的并發連接,同步阻塞模式是最好的。

異步回調和協程哪個性能好

協程雖然是用戶態調度,實際上還是需要調度的,既然調度就會存在上下文切換。所以協程雖然比操作系統進程性能要好,但總還是有額外消耗的。而異步回調是沒有切換開銷的,它等同于順序執行代碼。所以異步回調程序的性能是要優于協程模型的。

這里是指Nginx這種多進程異步非阻塞程序。Node.js/Redis此類程序如果不開多個進程,由于無法利用多核計算優勢,所以性能并不好。在Node.js中可以使用childprocess/cluster等擴展開啟多進程以解決此問題。

轉載于:https://my.oschina.net/wdyoschina/blog/681395

總結

以上是生活随笔為你收集整理的关于C10K、异步回调、协程、同步阻塞的全部內容,希望文章能夠幫你解決所遇到的問題。

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