## IO模型

[深入淺出Unix IO模型](https://mp.weixin.qq.com/s/I_KdtqBwq8IYfmtIJeUlyA)
[Linux IO模式及 select、poll、epoll詳解 - 人云思云 - SegmentFault 思否](https://segmentfault.com/a/1190000003063859)
[Linux編程之select - Madcola - 博客園](https://www.cnblogs.com/skyfsm/p/7079458.html)
> select系統調用的的用途是:在一段指定的時間內,監聽用戶感興趣的文件描述符上可讀、可寫和異常等事件。
>
> 從流程上來看,使用select函數進行IO請求和同步阻塞模型沒有太大的區別,甚至還多了添加監視socket,以及調用select函數的額外操作,效率更差。但是,使用select以后最大的優勢是用戶可以在一個線程內同時處理多個socket的IO請求。**用戶可以注冊多個socket,然后不斷地調用select讀取被激活的socket,即可達到在同一個線程內同時處理多個IO請求的目的。而在同步阻塞模型中,必須通過多線程的方式才能達到這個目的。**
>
> **對socket進行掃描時是線性掃描,即采用輪詢的方法,效率較低**:當套接字比較多的時候,每次select()都要通過遍歷FD_SETSIZE個Socket來完成調度,不管哪個Socket是活躍的,都遍歷一遍。這會浪費很多CPU時間。**如果能給套接字注冊某個回調函數,當他們活躍時,自動完成相關操作,那就避免了輪詢,這正是epoll與kqueue做的。**
*****
### 1. 阻塞式IO模型
**阻塞體現在:** 其系統調用直到數據包到達且被復制到應用進程的緩沖區或者發生錯誤時才返回,**在此期間會一直等待**(等待IO返回期間不能做任何事情)
**同步體現在:** 在等待的過程中,系統不提供通知服務,需要調用方一直等著知道系統IO完成。
**優點:** 簡單,容易理解,最符合我們對自上而下執行的代碼的理解。
**缺點:** 效率低下,不能充分利用機器性能。
> 實現最高效率就是要榨干機器的每一寸性能而不是在等待網絡IO時把CPU晾在一邊閑著
*****
### 2. 非阻塞式IO模型:
**非阻塞體現在:** 在IO沒有準備好數據時,recvfrom直接返回一個錯誤(`WSAEWOULDBLOCK` 錯誤),而不是被阻塞著而干不了其它事。
**同步體現在:** 在等待的過程中,系統不提供通知服務,需要調用方一直等著直到系統IO完成。
優點:與阻塞式IO相比,非阻塞IO效率有所提升。
缺點:需要不斷地主動獲取IO狀態(類似數據庫樂觀鎖的重試),效率不高
*****
### 3. IO復用模型
**復用體現在:** 1. 復用了什么?……
**阻塞體現在:** 用戶進程阻塞在select/poll上,而不是阻塞在具體的IO操作上,**不過由于是阻塞,所以還是做不了其它事。**
**異步體現在:** 在等待select的過程中,系統提供通知服務,你只需要等待select的通知就好。
**優點:** 用戶進程不用阻塞于具體的IO操作,而且多路復用器可以監聽多個IO文件描述符。
**缺點:** 內部實現中,監聽文件描述符是采用的輪詢的方式,效率不高。
[C10K問題 - 簡書](https://www.jianshu.com/p/ba7fa25d3590)
```
C10K問題的解決方案
從網絡編程技術的角度來說,主要思路:
每個連接分配一個獨立的線程/進程
同一個線程/進程同時處理多個連接
每個進程/線程處理一個連接
該思路最為直接,但是申請進程/線程是需要系統資源的,且系統需要管理這些進程/線程,所以會使資源占用過多,可擴展性差
```
> 每個進程/線程同時處理 多個連接(I/O多路復用)
>
> 復用少數幾個進程的處理多個客戶端連接 [PHP socket初探 --- select系統調用](https://blog.ti-node.com/blog/6389426571769282560)
*****
### 4. 信號驅動式IO模型
**非阻塞體現在:** 用戶進程只要調用sigaction(安裝信號處理器,定義信號處理的action)后**就能立即返回**,不會被阻塞。當操作系統的文件描述符就緒時,會發送信號給用戶進程,用戶進程再調用recvfrom開始IO操作。
**異步體現在:** 當前進程不受阻塞,在等待信號通知的過程中,可以繼續做其他事,**在操作系統的文件描述符就緒時,會發送信號給用戶進程,用戶進程再調用recvfrom開始IO操作。**
**優點:** 相較于IO復用模型效率提升了。
**缺點:** 沒有明顯缺點。
*****
### 5. 異步IO模型
**非阻塞體現在:** 只需要告訴(aio_read)操作系統當某個IO準備好后直接內核啟動某個操作,**就直接返回。**(注意這里的返回不是指退出)
**異步體現在:** 當前進程不受阻塞,在等待信號通知的過程中,可以繼續做其他事,而在該IO操作完成時操作系統內核會以發送信號的方式通知我們(通過aio_read中定義的信號處理器接收通知)。
**優點:** 相較于信號驅動式IO模型可以說是更進一步了,直接將等待IO和完成IO后的操作一并交給內核了。
**缺點:** 暫無缺點。
*****
### 總結
可以看到其實我們日常中寫的最多的代碼就是第一種,阻塞式IO模型,這也是最簡單的一種IO模型,就像自上而下執行的代碼那樣簡單直觀,是最容易理解和符合人類直觀的。
另外需要注意,無論是自己等待結果,或是自己輪詢結果,還是等待結果通知,這些都是需要自己不退出才行。
*****
### 名詞釋義
**阻塞/非阻塞:** 指事物/事件運行過程中相互依賴影響的關系,關注的是在等的過程中,還能不能干別的。
**同步/異步:** 指事物/事件運行過程中的依賴關系。
**串行/并行:** 指多個事物/事件運行順序關系(一般是多個相關聯的事物)
**并發/非并發:** 指一個系統同時為多人提供服務或同時提供多種服務的能力或模式。
*****
### 同步和異步的深入分析:
這個概念相對復雜一些,不那么容易理解,需要從多個方面去討論,才能理解得更加立體。
#### 1. 從最終如何獲得結果來看
**同步:** 靠自己一直等到結果。
**異步:** 不自己等,讓系統告訴你的結果。
**關注的是:** 從哪里得到結果,或是如何得到結果。對于等的這件事,你是靠自己一直等到結果,還是不自己等,讓系統告訴你的結果。重點的是你是如何得知結果的。
#### 2. 從與調用方對結果的依賴與否來看
**同步:** 調用方的繼續執行依賴于被調用方的返回結果。(需要調用方立即返回結果)
**異步:** 調用方的繼續執行不依賴于被調用方的返回結果。(不需要調用方立即返回結果)
**關注的是:** 調用方對被調用方返回結果的依賴性。
#### 同步在生活中的例子
>[tip] **不同場景下,“同步”這個詞所表示的意思可能是不同的,比如生活中“同步”往往表示;兩個事物的運行頻率或相互作用的關系,如:數據與XX保持同步更新;與XX團隊一起同步開展工作;走路時我們的步調保持同步一致;電機齒輪依靠同步帶同步轉動。**

生活中也有很多同步/同時的例子(異步的概念則在生活中應用很少),比如電機內部齒輪上的那個皮帶(套在兩個齒輪上),叫做同步帶,顯然,一個齒輪轉動時能通過同步帶來帶動另一個齒輪隨之轉動,此時兩個齒輪是同時,同步轉動的,**此處同步的意義是指兩個齒輪的相互作用,且轉動是同時發生的**。A轉動,B也隨之轉動;A停止,B也會同時停止。(注意這里并不是指齒輪轉動的角度,實際上兩個齒輪大小不一樣,轉動角度是不同的)
>[danger] **同步帶 是現在我唯一能找到的,可以證明兩個事件(轉動)是同時發生(并行)的案列。** (你還知道哪些其它生動的例子,期待你的留言!)
*****
### 參考
[還不懂 select, epoll 嗎?](https://mp.weixin.qq.com/s/71-X1urvqgFG08cxS4TNvA)
[你分得清分布式、高并發與多線程嗎?](https://mp.weixin.qq.com/s/8CutFewHv81jzhGBfOhd6w)
[面試官問:一個 TCP 連接可以發多少個 HTTP 請求?我懵了!](https://mp.weixin.qq.com/s/93-WoFTGeiW-8iduFs59hA)
[Spring Cloud 分布式服務限流實戰,已經為你排好了](https://mp.weixin.qq.com/s/dqvRpqkQBObKRjvpM-QgxQ)
[全球 IPv4 地址耗盡,IPv6 來了!](https://mp.weixin.qq.com/s/wMdDiu0o4JfUiqD8hAB75w)
[徹底搞懂高性能I/O之道](https://mp.weixin.qq.com/s/gSLIIOo3KJ3ihXNEcSbpKQ)
[她剛來,我就失寵了](https://mp.weixin.qq.com/s/EapnC7Bh8RVgp6c1q27PXA)
[現代 IM 系統中消息推送和存儲架構的實現](https://mp.weixin.qq.com/s/LBLaFMERpIB3UoYFEGV5WQ)
[還不懂 select, epoll 嗎?](https://mp.weixin.qq.com/s/71-X1urvqgFG08cxS4TNvA)
[java并發編程系列:wait/notify機制](https://mp.weixin.qq.com/s/OriB-ouTDuCzquoFmjv9Lg)(wait和sellp的區別)
[Linux驚群相關問題分析](https://mp.weixin.qq.com/s/ExRqSTBQ1_Z82SdgVUhOwg)
[來點硬核的:什么是RDMA?](https://mp.weixin.qq.com/s/b6NaCu0_M-__XHWpKODx6w)
[一個字節的網絡漫游故事獨白](https://mp.weixin.qq.com/s/EC5cgQ1ne9ZR0jFvznHBfg)
[集線器、交換機與路由器的區別](https://mp.weixin.qq.com/s/8KU4nZYstuK_qZesljipTg)
[微服務架構的理論基礎 - 康威定律](https://mp.weixin.qq.com/s/J7A2l8GKEi4NVC_rpUxIRg)
> 錯誤流淌在分布式系統的血液里。解決方法不是消滅這些問題,而是容忍這些問題,在問題發生時,能自動回復
[TCP 協議簡介](https://mp.weixin.qq.com/s/Ah8GJRAkPviYYtbxzNaxBQ)
[【系統編程】五種IO模型分析](https://mp.weixin.qq.com/s/9YXsJo_u2zVNqvABoGqfqg)
> 所謂的IO模型,描述的是出現I/O等待時進程的狀態以及處理數據的方式。
[【底層原理】網絡數據傳輸時經歷了哪些buffer](https://mp.weixin.qq.com/s/ZaQ6rpT_jOyaEtW7YPNXZw)
> 對node層不太了解 沒太看懂。。。我們的結構是html js css 全部署在cdn上,js訪問后端的api
> 這是最簡單普通的一種方案,但是不夠強大,還是用node + rpc的方式最好,是目前最好的方式。
[一個網卡的自述](https://mp.weixin.qq.com/s/JGsnWFhYPEwHwy7JsCNyNg)
[非阻塞 I/O 和多路復用+select、poll、epoll模型詳解](http://toutiao.com/group/6554223409138500110/?iid=31395168747&app=news_article_lite×tamp=1526046953&wxshare_count=1&tt_from=weixin&utm_source=weixin&utm_medium=toutiao_android&utm_campaign=client_share)
[張大胖的socket](https://mp.weixin.qq.com/s/XmWVy2ARauSBoehygs4Zvw)
[網絡編程 - NIO](https://mp.weixin.qq.com/s/fg36xDx--otVPACj391X0w)
[新手入門貼:史上最全Web端即時通訊技術原理詳解](http://www.52im.net/thread-338-1-1.html)
[手寫一個 WebSocket 協議](https://mp.weixin.qq.com/s/Tn81wt-_fWSbw_2gk2gmeg)
[PHP Socket編程進階指南](https://cloud.tencent.com/developer/news/271302)
[Java 線程通信之 wait/notify 機制](https://mp.weixin.qq.com/s/x6jt8R0czfcsTolnZwVZmQ)
[面試官:MAC 地址為什么不需要全球唯一?](https://mp.weixin.qq.com/s/ihjNnqgJty7YKC94sJ-0PA)
[超強圖文|并發編程【等待/通知機制】就是這個feel~](https://mp.weixin.qq.com/s/o6Yse51tPLv27GVq22ifyA)
[使用虛幻引擎 4 年,再談談它的網絡架構](https://mp.weixin.qq.com/s/qKg3iVHZYhqpmNXDfc1pjA)
[Linux服務端最大并發數是多少?](https://mp.weixin.qq.com/s/YIVrgFUZADcSwCrV1q-yaA)
[中斷還是輪詢?取個數據包真麻煩!](https://mp.weixin.qq.com/s/QmZP0P4BrSJ1p6YI6cmyVQ)
[為什么像王者榮耀這樣的游戲 Server 不愿意使用微服務?](https://mp.weixin.qq.com/s/PGFlbKwZQvAjX1e5bqNzxg)
[如何用一行代碼讓 gevent 爬蟲提速 100%](https://mp.weixin.qq.com/s/eZK5qevjACdNfq-PyqpG7Q)
[Redis 6.0 除了多線程,這個功能也賊牛逼!](https://mp.weixin.qq.com/s/6e0gahpYWpIBSFpTBBpEgg)
[完了!TCP出了大事!](https://mp.weixin.qq.com/s/iBk-kEj2tJqMCuFOdXCLEA)
[圖解Linux網絡包接收過程](https://mp.weixin.qq.com/s/GoYDsfy9m0wRoXi_NCfCmg)
[CPU:網卡老哥,你到底怎么工作的?](https://mp.weixin.qq.com/s/9E_pl_V2brzgmX3PfedwlQ)
[框架篇:linux網絡I/O+Reactor模型](https://mp.weixin.qq.com/s/Nv7h7a_mhOsG1kLYz6OueA)
[程序員應如何理解高并發中的協程](https://mp.weixin.qq.com/s/dSY1c1rKh6h5XT3ds0EyKg)
[點個外賣,我把「軟中斷」搞懂了](https://mp.weixin.qq.com/s?__biz=MzUxODAzNDg4NQ==&mid=2247487248&idx=1&sn=9a1bde19deb1cf734db164d705b7c468&chksm=f98e4bbacef9c2ac7a9e299038fa06f69e0a87ad3d88fdb6874c3c482d3a39a36bd1b6e2bde4&scene=132#wechat_redirect)
[今天我“蹂躪”了一個包](https://mp.weixin.qq.com/s/PzzGZb9Y4lSHIjmW4ai9HA)
[本文把TCP/IP講絕了!](https://mp.weixin.qq.com/s/4_WbTXwiJPNxBa8Rq28ROg)
~~~
我想認識你下,這是我的電話(期待回信)
好的,收到你的電話了,這是我的電話(期待回信)
嗯啦,我也收到你的電話了,我們開始交往吧
...
我覺得我們該結束了(期待回復)
你確認你已經不愛我了嗎,想好再說(期待回復)
確認,想好了,我們分開吧(期待回復)
好,尊重你的意愿,好聚好散,保重
(錯,并不是這樣的)
我對你已經沒有感情了 (女)
我知道了 (男)
我對你也沒有感情了(男)
我知道了 (女)(男收到后就關閉)
(女等待 2msl 沒回應后才關閉)(先說放手的人才是不愿放手的人,她還抱有期待,如果這 2msl 內他有回音,說后悔了,哪怕是簡單的一句問候,她愿意放下卑微的尊嚴,奮不顧身的再愛他一次,在感情面前講什么自我,要再次撲到懷里大哭一場,要痛痛快快的訴說所有的委屈和不甘,...,可是沒有如果,愛得最深的人總是最敏感,最容易受傷,明明知道自己想要什么,可總是讓自己歇斯底里遍體鱗傷。問世間情為何物,愿得一人心白首不分離)
~~~
~~~
三次握手:
A:你好,想認識你,這是我的微信
B:好啊,這是我的微信,我看到你的微信了 (A 求認識成功)
A:嗯,我也看到你的微信了 (B交友成功)
四次揮手:
A:我不愛你了
B:我知道了
B:我也不愛你了
A:好,后會無期
A發出后等待2MSL(最長報文段壽命,確保消息發出去)后斷開連接,B收到后就立即斷開連接
說放手的那個人才是最舍不得的那個人
link:
https://www.cnblogs.com/skynet/archive/2010/12/12/1903949.html
https://blog.csdn.net/qq\_38950316/article/details/81087809
~~~
[從一個程序員的角度告訴你:“12306”有多牛逼?](https://mp.weixin.qq.com/s/O9I_HcF_rAWur1sCi_eKfA)
> 自 Epoll 網絡架構模型解決了 c10k 問題以來,異步越來越被服務端開發人員所接受,能夠用異步來做的工作,就用異步來做,在功能拆解上能達到意想不到的效果。
? 這點在 Nginx、Node.JS、Redis 上都能體現,他們處理網絡請求使用的 Epoll 模型,用實踐告訴了我們單線程依然可以發揮強大的威力。
[程序員怎么會不知道 C10K 問題呢?](https://mp.weixin.qq.com/s/MX4Kt8wiuhTEN1UxtWEqMQ)
[從HTTP到HTTP/3的發展簡史](https://mp.weixin.qq.com/s/ROiUE9qUEo7rYdOME0c2Rg)
> UDP 是一種無狀態協議(持久連接只是其之上的抽象)
>
> UDP 是一種無狀態協議(持久連接只是其之上的抽象),**使 QUIC 能夠支持一些很大程度上忽略了數據包傳遞復雜性的功能。例如,從理論上講,客戶端更改其 IP 地址中間連接(例如智能手機從移動網絡跳轉到家庭 wifi)時不應中斷連接,因為該協議允許在不同 IP 地址之間遷移而無需重新連接。**
>
> 這和TCP四元組連接有什么不同嗎?連接的本質是什么?
[QUIC 0-RTT實現簡析及一種分布式的0-RTT實現方案](https://cloud.tencent.com/developer/article/1594468)
[漫畫:一臺 Linux 服務器最多能支撐多少個 TCP 連接](https://mp.weixin.qq.com/s/gsoESy5viCgX0wXqUi4QPw)
[圖解 QUIC](https://cangsdarm.github.io/illustrate/quic)
[revoltphp/event-loop: Revolt is a rock-solid event loop for concurrent PHP applications. --- revoltphp/event-loop:Revolt 是用于并發 PHP 應用程序的堅如磐石的事件循環。](https://github.com/revoltphp/event-loop)
*****
last update:2018-10-21 15:33:41
- 開始
- 公益
- 更好的使用看云
- 推薦書單
- 優秀資源整理
- 技術文章寫作規范
- SublimeText - 編碼利器
- PSR-0/PSR-4命名標準
- php的多進程實驗分析
- 高級PHP
- 進程
- 信號
- 事件
- IO模型
- 同步、異步
- socket
- Swoole
- PHP擴展
- Composer
- easyswoole
- php多線程
- 守護程序
- 文件鎖
- s-socket
- aphp
- 隊列&并發
- 隊列
- 講個故事
- 如何最大效率的問題
- 訪問式的web服務(一)
- 訪問式的web服務(二)
- 請求
- 瀏覽器訪問阻塞問題
- Swoole
- 你必須理解的計算機核心概念 - 碼農翻身
- CPU阿甘 - 碼農翻身
- 異步通知,那我要怎么通知你啊?
- 實時操作系統
- 深入實時 Linux
- Redis 實現隊列
- redis與隊列
- 定時-時鐘-阻塞
- 計算機的生命
- 多進程/多線程
- 進程通信
- 拜占庭將軍問題深入探討
- JAVA CAS原理深度分析
- 隊列的思考
- 走進并發的世界
- 鎖
- 事務筆記
- 并發問題帶來的后果
- 為什么說樂觀鎖是安全的
- 內存鎖與內存事務 - 劉小兵2014
- 加鎖還是不加鎖,這是一個問題 - 碼農翻身
- 編程世界的那把鎖 - 碼農翻身
- 如何保證萬無一失
- 傳統事務與柔性事務
- 大白話搞懂什么是同步/異步/阻塞/非阻塞
- redis實現鎖
- 淺談mysql事務
- PHP異常
- php錯誤
- 文件加載
- 路由與偽靜態
- URL模式之分析
- 字符串處理
- 正則表達式
- 數組合并與+
- 文件上傳
- 常用驗證與過濾
- 記錄
- 趣圖
- foreach需要注意的問題
- Discuz!筆記
- 程序設計思維
- 抽象與具體
- 配置
- 關于如何學習的思考
- 編程思維
- 談編程
- 如何安全的修改對象
- 臨時
- 臨時筆記
- 透過問題看本質
- 程序后門
- 邊界檢查
- session
- 安全
- 王垠
- 第三方數據接口
- 驗證碼問題
- 還是少不了虛擬機
- 程序員如何談戀愛
- 程序員為什么要一直改BUG,為什么不能一次性把代碼寫好?
- 碎碎念
- 算法
- 實用代碼
- 相對私密與絕對私密
- 學習目標
- 隨記
- 編程小知識
- foo
- 落盤
- URL編碼的思考
- 字符編碼
- Elasticsearch
- TCP-IP協議
- 碎碎念2
- Grafana
- EFK、ELK
- RPC
- 依賴注入
- 科目一
- 開發筆記
- 經緯度格式轉換
- php時區問題
- 解決本地開發時調用遠程AIP跨域問題
- 后期靜態綁定
- 談tp的跳轉提示頁面
- 無限分類問題
- 生成微縮圖
- MVC名詞
- MVC架構
- 也許模塊不是唯一的答案
- 哈希算法
- 開發后臺
- 軟件設計架構
- mysql表字段設計
- 上傳表如何設計
- 二開心得
- awesomes-tables
- 安全的代碼部署
- 微信開發筆記
- 賬戶授權相關
- 小程序獲取是否關注其公眾號
- 支付相關
- 提交訂單
- 微信支付筆記
- 支付接口筆記
- 支付中心開發
- 下單與支付
- 支付流程設計
- 訂單與支付設計
- 敏感操作驗證
- 排序設計
- 代碼的運行環境
- 搜索關鍵字的顯示處理
- 接口異步更新ip信息
- 圖片處理
- 項目搭建
- 閱讀文檔的新方式
- mysql_insert_id并發問題思考
- 行鎖注意事項
- 細節注意
- 如何處理用戶的輸入
- 不可見的字符
- 抽獎
- 時間處理
- 應用開發實戰
- python 學習記錄
- Scrapy 教程
- Playwright 教程
- stealth.min.js
- Selenium 教程
- requests 教程
- pyautogui 教程
- Flask 教程
- PyInstaller 教程
- 蜘蛛
- python 文檔相似度驗證
- thinkphp5.0數據庫與模型的研究
- workerman進程管理
- workerman網絡分析
- java學習記錄
- docker
- 筆記
- kubernetes
- Kubernetes
- PaddlePaddle
- composer
- oneinstack
- 人工智能 AI
- 京東
- pc_detailpage_wareBusiness
- doc
- 電商網站設計
- iwebshop
- 商品規格分析
- 商品屬性分析
- tpshop
- 商品規格分析
- 商品屬性分析
- 電商表設計
- 設計記錄
- 優惠券
- 生成唯一訂單號
- 購物車技術
- 分類與類型
- 微信登錄與綁定
- 京東到家庫存系統架構設計
- crmeb
- 命名規范
- Nginx https配置
- 關于人工智能
- 從人的思考方式到二叉樹
- 架構
- 今日有感
- 文章保存
- 安全背后: 瀏覽器是如何校驗證書的
- 避不開的分布式事務
- devops自動化運維、部署、測試的最后一公里 —— ApiFox 云時代的接口管理工具
- 找到自己今生要做的事
- 自動化生活
- 開源與漿果
- Apifox: API 接口自動化測試指南