在進行網絡編程時,常常見到同步(Sync)/異步(Async),阻塞(Block)/非阻塞(Unblock)四種調用方式
同步/異步主要針對C端:
同步:c端發出一個功能調用時,在沒有得到結果之前,c端死等結果
例如:普通B/S模式(同步):提交請求->等待服務器處理->處理完畢返回 這個期間客戶端浏覽器不能干任何事
異步:c端一個異步過程調用發出後,調用者不會立刻得到結果。實際處理這個調用的部件在完成後,通過狀態、通知和回調來通知調用者。
例如:ajax請求(異步): 事件觸發->服務器處理(浏覽器可做其他的)->處理完畢,ajax回調函數處理結果
阻塞/非阻塞主要針對S端:
阻塞(等待):阻塞調用是指調用結果返回之前,當前線程會被掛起。函數只有在得到結果之後才會返回,效率低
<?php $fp = fopen("lock.txt", "w+"); if(flock($fp,LOCK_EX)) { //..處理訂單 flock($fp,LOCK_UN); } fclose($fp); ?>
非阻塞(立即返回):指在不能立刻得到結果之前,該函數不會阻塞當前線程,而會立刻返回,效率高,適合高並發
<?php $fp = fopen("lock.txt", "w+"); if(flock($fp,LOCK_EX | LOCK_NB)) { //..處理訂單 flock($fp,LOCK_UN); } else { echo "系統繁忙,請稍後再試"; } fclose($fp); ?>
同步、異步和阻塞、非阻塞是組合關系,因此有4種方式:
同步阻塞、同步非阻塞、異步阻塞、異步非阻塞
linux有五種I/O模型
1)阻塞I/O(blocking I/O)
2)非阻塞I/O (nonblocking I/O)
3)I/O復用(select 和poll) (I/O multiplexing)
4)信號驅動I/O (signal driven I/O (SIGIO))
5)異步I/O (asynchronous I/O (the POSIX aio_functions))
前四種都是同步,只有最後一種才是異步IO
select、poll、epoll 區別總結:
1、單進程最大連接數:
select:單個進程所能打開的最大連接數有FD_SETSIZE宏定義
poll:poll本質上和select沒有區別,但是它沒有最大連接數的限制,原因是它是基於鏈表來存儲的
epoll:雖然連接數有上限,但是很大,1G內存的機器上可以打開10萬左右的連接,2G內存的機器可以打開20萬左右的連接
2、文件描述符(FD)劇增後帶來的IO效率問題
select:每次調用文件描述符(FD)時都會對連接進行線性遍歷,所以隨著FD的增加會造成遍歷速度慢的"線性下降性能問題"
poll:同上
epoll:根據每個fd上的callback函數來實現的,只有活躍的socket才會主動調用callback,所以在活躍socket較少的情況下,使用epoll沒有前面兩者的線性下降的性能問題,但是所有socket都很活躍的情況下,可能會有性能問題。
3、 消息傳遞方式
select:內核需要將消息傳遞到用戶空間,都需要內核拷貝動作
poll:同上
epoll:epoll通過內核和用戶空間共享一塊內存來實現的。
總結:
綜上,在選擇select,poll,epoll時要根據具體的使用場合以及這三種方式的自身特點。
1、表面上看epoll的性能最好,但是在連接數少並且連接都十分活躍的情況下,select和poll的性能可能比epoll好,畢竟epoll的通知機制需要很多函數回調。
2、select低效是因為每次它都需要輪詢。但低效也是相對的,視情況而定,也可通過良好的設計改善
以上這篇淺談socket同步和異步、阻塞和非阻塞、I/O模型就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持幫客之家。