linux select read阻塞_linux下的IO模型详解
開門見山,Linux下的如中IO模型:阻塞IO模型,非阻塞IO模型,IO復用模型,信號驅動IO模型,異步IO模型,見下圖
接下來一一講解這5種模型
阻塞型IO:最簡單的一種IO模型,簡單理解就是死等,即進程或線程一直等待莫格條件,不滿足則一直等待。
非阻塞型IO:應用進程與內(nèi)核交互,目的未達到之前會直接返回,然后不斷輪詢,不停的去問內(nèi)核數(shù)據(jù)是否準備好?如果發(fā)現(xiàn)準備好了,那就把數(shù)據(jù)拷貝到用戶空間中。應用進程通過
recvfrom 調用不停的去和內(nèi)核交互,直到內(nèi)核準備好數(shù)據(jù)。如果沒有準備好,內(nèi)
核會返回error,應用進程在得到error后,過一段時間再發(fā)送recvfrom請求。在兩次發(fā)送請求的時間段,進程可以先做別的事情。
信號驅動IO:我們會發(fā)現(xiàn)非阻塞型IO方式一遍一遍的輪詢不如等內(nèi)核把數(shù)據(jù)準備好,然后通知進程,當進程收到該通知時,便開始把數(shù)據(jù)拷貝到用戶空間中。
即應用進程預先向內(nèi)核注冊一個信號處理函數(shù),然后用戶進程返回,并不阻塞,當內(nèi)核數(shù)據(jù)準備就緒時會發(fā)送一個信號給進程,用戶進程便在信號處理函數(shù)中開始把數(shù)據(jù)拷貝到用戶空間中
IO復用模型:顧名思義,即將多個進程I/0注冊到同一管道上,這里管道會統(tǒng)一和內(nèi)核交互。當管道中的某一個請求需要好的數(shù)據(jù)準備好之后,進程再把對應的數(shù)據(jù)拷貝到用戶空間中。I/O多路轉接是多了一個Select函數(shù),多個進程的IO可以注冊到同一個Select中,用戶調用該Select。Select會監(jiān)聽所有注冊好的I/O,如果所有被監(jiān)聽的I/O需要的數(shù)據(jù)都沒有準備好,Select調用進程會阻塞。當任意一個I/O所需要的數(shù)據(jù)準備好之后,Select調用就
會返回,然后進程再通過recvfrom來進行數(shù)據(jù)拷貝。但實際上,它并未向內(nèi)核注冊信號處理函數(shù),所以它并不是非阻塞的。
看到開篇的那張圖,大家肯定會有疑問,為什么之前的這四種模型都是同步的呢?因為無論以上哪種模型,真正的數(shù)據(jù)拷貝過程都是同步的(自己的理解便是:所有的數(shù)據(jù)拷貝過程都是用戶進程手動執(zhí)行的) 分享一個Linux IO的參考資料:http://makeru.com.cn/live/4011_1565.html?s=45051
那么我們來看真正異步執(zhí)行的I/O模型:
異步I/O模型:應用進程把I/O請求傳給內(nèi)核后,完全由內(nèi)核去操作文件拷貝。內(nèi)核完成相關操作后,會發(fā)信號告訴應用進程本次I/O已經(jīng)完成。用戶進程發(fā)起aio_read操作之后,給內(nèi)核傳遞描述符、緩沖區(qū)指針、緩沖區(qū)大小等,告訴內(nèi)核進程當整個操作完成時,如何通知進程,然后就立刻去做其他事兒了。當內(nèi)核收到aio_read后,會立刻返回,然后內(nèi)核開始等待數(shù)據(jù)準備,數(shù)據(jù)準備好以后,直接把數(shù)據(jù)拷貝到用戶控件,然后再通知進程本次IO已經(jīng)完成。
更多交流學習可以私我昵稱wx號 各個模型的執(zhí)行流程比較圖如下圖所示
總結
以上是生活随笔為你收集整理的linux select read阻塞_linux下的IO模型详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: matlab imread_matlab
- 下一篇: linux启动redis_Redis简介