淺談socket同步和異步、阻塞和非阻塞、I/O模型
在進(jìn)行網(wǎng)絡(luò)編程時(shí),常常見到同步(Sync)/異步(Async),阻塞(Block)/非阻塞(Unblock)四種調(diào)用方式
同步/異步主要針對(duì)C端:
同步:c端發(fā)出一個(gè)功能調(diào)用時(shí),在沒有得到結(jié)果之前,c端死等結(jié)果
例如:普通B/S模式(同步):提交請(qǐng)求->等待服務(wù)器處理->處理完畢返回 這個(gè)期間客戶端瀏覽器不能干任何事
異步:c端一個(gè)異步過程調(diào)用發(fā)出后,調(diào)用者不會(huì)立刻得到結(jié)果。實(shí)際處理這個(gè)調(diào)用的部件在完成后,通過狀態(tài)、通知和回調(diào)來通知調(diào)用者。
例如:ajax請(qǐng)求(異步): 事件觸發(fā)->服務(wù)器處理(瀏覽器可做其他的)->處理完畢,ajax回調(diào)函數(shù)處理結(jié)果
阻塞/非阻塞主要針對(duì)S端:
阻塞(等待):阻塞調(diào)用是指調(diào)用結(jié)果返回之前,當(dāng)前線程會(huì)被掛起。函數(shù)只有在得到結(jié)果之后才會(huì)返回,效率低
<?php $fp = fopen("lock.txt", "w+"); if(flock($fp,LOCK_EX)) { //..處理訂單 flock($fp,LOCK_UN); } fclose($fp); ?>
非阻塞(立即返回):指在不能立刻得到結(jié)果之前,該函數(shù)不會(huì)阻塞當(dāng)前線程,而會(huì)立刻返回,效率高,適合高并發(fā)
<?php $fp = fopen("lock.txt", "w+"); if(flock($fp,LOCK_EX | LOCK_NB)) { //..處理訂單 flock($fp,LOCK_UN); } else { echo "系統(tǒng)繁忙,請(qǐng)稍后再試"; } fclose($fp); ?>
同步、異步和阻塞、非阻塞是組合關(guān)系,因此有4種方式:
同步阻塞、同步非阻塞、異步阻塞、異步非阻塞
linux有五種I/O模型
1)阻塞I/O(blocking I/O)
2)非阻塞I/O (nonblocking I/O)
3)I/O復(fù)用(select 和poll) (I/O multiplexing)
4)信號(hào)驅(qū)動(dòng)I/O (signal driven I/O (SIGIO))
5)異步I/O (asynchronous I/O (the POSIX aio_functions))
前四種都是同步,只有最后一種才是異步IO
select、poll、epoll 區(qū)別總結(jié):
1、單進(jìn)程最大連接數(shù):
select:?jiǎn)蝹€(gè)進(jìn)程所能打開的最大連接數(shù)有FD_SETSIZE宏定義
poll:poll本質(zhì)上和select沒有區(qū)別,但是它沒有最大連接數(shù)的限制,原因是它是基于鏈表來存儲(chǔ)的
epoll:雖然連接數(shù)有上限,但是很大,1G內(nèi)存的機(jī)器上可以打開10萬左右的連接,2G內(nèi)存的機(jī)器可以打開20萬左右的連接
2、文件描述符(FD)劇增后帶來的IO效率問題
select:每次調(diào)用文件描述符(FD)時(shí)都會(huì)對(duì)連接進(jìn)行線性遍歷,所以隨著FD的增加會(huì)造成遍歷速度慢的"線性下降性能問題"
poll:同上
epoll:根據(jù)每個(gè)fd上的callback函數(shù)來實(shí)現(xiàn)的,只有活躍的socket才會(huì)主動(dòng)調(diào)用callback,所以在活躍socket較少的情況下,使用epoll沒有前面兩者的線性下降的性能問題,但是所有socket都很活躍的情況下,可能會(huì)有性能問題。
3、 消息傳遞方式
select:內(nèi)核需要將消息傳遞到用戶空間,都需要內(nèi)核拷貝動(dòng)作
poll:同上
epoll:epoll通過內(nèi)核和用戶空間共享一塊內(nèi)存來實(shí)現(xiàn)的。
總結(jié):
綜上,在選擇select,poll,epoll時(shí)要根據(jù)具體的使用場(chǎng)合以及這三種方式的自身特點(diǎn)。
1、表面上看epoll的性能最好,但是在連接數(shù)少并且連接都十分活躍的情況下,select和poll的性能可能比epoll好,畢竟epoll的通知機(jī)制需要很多函數(shù)回調(diào)。
2、select低效是因?yàn)槊看嗡夹枰喸?。但低效也是相?duì)的,視情況而定,也可通過良好的設(shè)計(jì)改善
以上這篇淺談socket同步和異步、阻塞和非阻塞、I/O模型就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
簡(jiǎn)單的cookie計(jì)數(shù)器實(shí)現(xiàn)源碼
本篇文章是對(duì)一個(gè)簡(jiǎn)單的cookie計(jì)數(shù)器的實(shí)現(xiàn)源碼進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06php中時(shí)間函數(shù)date及常用的時(shí)間計(jì)算
本篇文章主要介紹了php中時(shí)間函數(shù)date及常用的時(shí)間計(jì)算的相關(guān)知識(shí),具有很好的參考價(jià)值。下面跟著小編一起來看下吧2017-05-05PHP擴(kuò)展mcrypt實(shí)現(xiàn)的AES加密功能示例
這篇文章主要介紹了PHP擴(kuò)展mcrypt實(shí)現(xiàn)的AES加密功能,結(jié)合實(shí)例形式分析了php基于mcrypt實(shí)現(xiàn)AES加密的相關(guān)操作技巧,需要的朋友可以參考下2019-01-01THINKPHP在添加數(shù)據(jù)的時(shí)候獲取主鍵id的值方法
下面小編就為大家?guī)硪黄猅HINKPHP在添加數(shù)據(jù)的時(shí)候獲取主鍵id的值方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-04-04php源碼分析之DZX1.5字符串截?cái)嗪瘮?shù)cutstr用法
這篇文章主要介紹了php源碼分析之DZX1.5字符串截?cái)嗪瘮?shù)cutstr用法,實(shí)例分析了DZX1.5中cutstr函數(shù)實(shí)現(xiàn)字符串截取的使用技巧,需要的朋友可以參考下2015-06-06PHP實(shí)現(xiàn)的簡(jiǎn)單分頁類及用法示例
這篇文章主要介紹了PHP實(shí)現(xiàn)的簡(jiǎn)單分頁類及用法,結(jié)合實(shí)例形式分析的PHP分頁類的功能、定義與具體使用技巧,需要的朋友可以參考下2016-05-05