同步IO和非同步IO

2021-08-25 03:34:50 字數 4061 閱讀 8695

同步io和非同步io

有兩種型別的檔案io

同步:同步檔案io

和非同步檔案io

。非同步檔案io

也就是重疊io

。在同步檔案io

中,執行緒啟動乙個io

操作然後就立即進入等待狀態,直到io

操作完成後才醒來繼續執行。而非同步檔案io

方式中,執行緒傳送乙個io

請求到核心,然後繼續處理其他的事情,核心完成io

請求後,將會通知執行緒io

操作完成了。

如果io

請求需要大量時間執行的話,非同步檔案io

將會排程其他執行緒進行執行,如果沒有其他執行緒需要執行的話,這段時間將會浪費掉(可能會排程作業系統的零頁執行緒)。如果io

請求操作很快,用非同步io

方式反而還低效,還不如用同步io

方式。同步io

在同一時刻只允許乙個io

操作,也就是說對於同乙個檔案控制代碼的io

操作是序列化的,即使使用兩個執行緒也不能同時對同乙個檔案控制代碼同時發出讀寫操作。重疊io

允許乙個或多個執行緒同時發出io

請求。非同步io

察看io

請求是否完成,也可以通過乙個事件物件來通知應用程式。

簡單的說「同步在程式設計裡,一般是指某個io操作執行完後,才可以執行後面的操作。非同步則是,將某個操作給系統,主線程去忙別的事情,等核心完成操作後通知主線程非同步操作已經完成。」

i、windows同步i/o與非同步i/o

**:

dwordnreadbyte;

bytebbuf[buf_size];

readfile(hfile,bbuf,sizeof(bbuf),&nreadbyte,&ov);

//由於此時hevent=null,所以同步物件為hfile,下面兩句的效果一樣

waitforsingleobject(hfile,infinite);

**:

dwordnreadbyte;

bytebbuf1[buf_size],bbuf2[buf_size],bbuf3[buf_size];

readfile(hfile,bbuf1,sizeof(bbuf1),&nreadbyte,&ov1);

readfile(hfile,bbuf2,sizeof(bbuf2),&nreadbyte,&ov2);

readfile(hfile,bbuf3,sizeof(bbuf3),&nreadbyte,&ov3);

//假設三個i/o處理的時間比較長,到這裡還沒有結束

**:

dwordnreadbyte;

bytebbuf1[buf_size],bbuf2[buf_size],bbuf3[buf_size];

handlehevent1=createevent(null,false,false,null);

handlehevent2=createevent(null,false,false,null);

handlehevent3=createevent(null,false,false,null);

readfile(hfile,bbuf1,sizeof(bbuf1),&nreadbyte,&ov1);

readfile(hfile,bbuf2,sizeof(bbuf2),&nreadbyte,&ov2);

readfile(hfile,bbuf3,sizeof(bbuf3),&nreadbyte,&ov3);

//此時3個i/o操作的同步物件分別為hevent1,hevent2,hevent3

**:

voidccompletionroutinedlg::ontest()

deletefile("a.txt");

deletefile("b.txt");

deletefile("c.txt");

}

執行後的效果如下(winxp+sp2+vc6.0):

4、心得體會

每當乙個io操作結束時會產生乙個完成資訊,如果該io操作有完成例程的話就新增到完成例程佇列。一旦呼叫執行緒進入可變等待狀態,就會依次執行佇列中的完成例程。

在這個示例中還有乙個問題,如果把這個軟體放在系統分割槽的檔案目錄下可以正常執行,而放在其他碟符下就會出現問題,執行結果就不同,真是奇怪了。

四、使用完成埠(iocp)

例項二、使用iocp的非同步i/o示例

1、設計目標

體會完成埠的非同步i/o實現原理及過程。

2、問題的分析與設計

說明:每個客戶端與乙個管道進行互動,而在互動過程中i/o操作結束後產生的完成包就會進入「i/o完成包佇列」。完成埠的執行緒佇列中的執行緒使用getqueuedcompletionstatus來檢測「i/o完成包佇列」中是否有完成包資訊。

3、詳細設計(關鍵**如下)

**:uintserverthread(lpvoidlpparameter)

return0;

}voidcmydlg::onstart()

//建立執行緒

for(i=0;i……}

voidcmydlg::onstop()

for(i=0;i……}

4、心得體會

上面這個例子是關於完成埠的簡單應用。可以這樣來理解完成埠,它與三種資源相關分別是管道、i/o完成包佇列、執行緒佇列,它的作用是協調這三種資源。

參考:

ii、linux同步i/o與非同步i/o

linux

中sio(同步io)和aio(非同步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使用的是相同的機制,同步阻塞。

同步IO和非同步IO

同步io和非同步io 簡單的說 同步在程式設計裡,一般是指某個io操作執行完後,才可以執行後面的操作。非同步則是,將某個操作給系統,主線程去忙別的事情,等核心完成操作後通知主線程非同步操作已經完成。i windows同步i o與非同步i o 執行後的效果如下 winxp sp2 vc6.0 4 心得...

同步IO和非同步IO

同步io和非同步io 有兩種型別的檔案io同步 同步檔案io和非同步檔案io。非同步檔案io也就是重疊io。在同步檔案io中,執行緒啟動乙個io操作然後就立即進入等待狀態,直到io操作完成後才醒來繼續執行。而 非同步檔案io方式中,執行緒傳送乙個io請求到核心,然後繼續處理其他的事情,核心完成io請...

同步IO和非同步IO

同步和非同步是針對應用程式和核心互動而言,同步是指使用者出發io操作並等待或者輪詢的去檢視io操作是否就緒 而非同步是指使用者程序出發io操作以後便開始做自己的事情,而當io操作完成後,會非同步通知使用者程序。同步io和非同步io指的是使用者空間和核心空間資料互動的方式 同步io 使用者空間需要的資...