1. 程式人生 > >Linux的非同步IO機制(轉)

Linux的非同步IO機制(轉)

1.read/write:
對於read操作來說,它是同步的。也就是說只有當申請讀的內容真正存放到buffer中後(user mode的buffer),read函式才返回。在此期間,它會因為等待IO完成而被阻塞。研究過原始碼的朋友應該知道,這個阻塞發生在兩個地方:一是read操作剛剛發起,kernel會檢查其它程序的need_sched標誌,如果有其它程序需要排程,主動阻塞read操作,這個時候其實I/O操作還沒有發起。二是I/O操作發起後,呼叫lock_page對已經加鎖的頁面申請鎖,這時由於頁面已經加鎖,所以加鎖操作被阻塞,從而read操作阻塞,直到I/O操作完成後頁面被解鎖,read操作繼續執行。所以說read是同步的,其阻塞的原因如上。
對於write操作通常是非同步的。因為linux中有page cache機制,所有的寫操作實際上是把檔案對應的page cache中的相應頁設定為dirty,然後write操作返回。這個時候對檔案的修改並沒有真正寫到磁碟上去。所以說write是非同步的,這種方式下write不會被阻塞。如果設定了O_SYNC標誌的檔案,write操作再返回前會把修改的頁flush到磁碟上去,發起真正的I/O請求,這種模式下會阻塞。
2.Direct I/O
linux支援Direct I/O, 以O_DIRCET標誌開啟的檔案,在read和write的時候會繞開page cache,直接使用user mode的buffer做為I/O操作的buffer。這種情況下的read和write直接發起I/O操作,都是同步的,並會被阻塞。
3.AIO
目前大多數的linux用的AIO是基於2.4核心中的patch,使用librt庫中的介面。這種方式實現很簡單,就是一個父程序clone出子程序幫其做I/O,完成後通過signal或者callback通知父程序。使用者看來是AIO,實質還是SIO。linux kernel中AIO的實現概念類似,只不過是以一組kernel thread去做的。這些kernel thread做I/O的時候使用的是和Direct I/O相同的方式。
4.mmap()
拋開它中講vm_area和page cache對映在一起的機制不說。真正發起I/O時和read、write使用的是相同的機制,同步阻塞。