1. 程式人生 > >socket同步和非同步、阻塞和非阻塞、I/O模型

socket同步和非同步、阻塞和非阻塞、I/O模型

在進行網路程式設計時,常常見到同步(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低效是因為每次它都需要輪詢。但低效也是相對的,視情況而定,也可通過良好的設計改善