110 likes | 195 Views
Other Thread Synchronization Functions. 井民全製作. Introduction. Asynchronous I/O 架構. 主要的 thread 發出 I/O 的動作 繼續後面 的工作 當 I/O 完成時 , 自動呼叫 call back fuction. WriteFileEx. 處理 I/O. 1. I/O 完成 2. 主 thread 進入 Alerable 狀態. 繼續工作. Call back 處理函式. SleepEx(INFINITE,TRUE).
E N D
Asynchronous I/O 架構 • 主要的 thread 發出 I/O 的動作 • 繼續後面的工作 • 當 I/O 完成時, 自動呼叫 call back fuction WriteFileEx 處理I/O 1. I/O完成 2. 主 thread 進入Alerable 狀態 繼續工作 Call back 處理函式 SleepEx(INFINITE,TRUE)
Asynchronous Write void ShowError(); VOID CALLBACK IoCompletionRoutine(DWORD dwErrorCode,DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped); #include <iostream> using namespace std; int main(int argc, TCHAR* argv[], TCHAR* envp[]){ HANDLE hFile = CreateFile(_T("c:\\myfile.txt"), // file to create GENERIC_WRITE, // open for writing 0, // do not share NULL, // default security CREATE_ALWAYS, // overwrite existing FILE_ATTRIBUTE_NORMAL | // normal file FILE_FLAG_OVERLAPPED, // asynchronous I/O NULL); // no attr. template if (hFile == INVALID_HANDLE_VALUE) { ShowError(); return -1; } 完整範例: AsynchronousWriteDemo
// Step 1: 配置 Overlapped 結構 空間 LPOVERLAPPED Overlapped; Overlapped =(LPOVERLAPPED) LocalAlloc(LMEM_ZEROINIT, sizeof(OVERLAPPED)); if(!Overlapped){ ShowError(); return -1; } // Step 2: 定義要寫入的資料 Overlapped->Offset = 0; // 設定起始寫入指標(low word) Overlapped->OffsetHigh = 0; // 起始寫入指標(high word) LPTSTR lpBuffer=_T("jING_TEST"); // 指定要寫入的資料 DWORD dwTransferCount=lstrlen(lpBuffer)*sizeof(TCHAR); // 計算寫入資料的長度 (byte) // Step 3: 非同步寫入 BOOL bSucc=WriteFileEx(hFile,lpBuffer, dwTransferCount, Overlapped ,IoCompletionRoutine); if(!bSucc){ ShowError(); } // Step 4: 作其他事情 for(int i=0;i<10;i++){ cout << i <<"秒"<< endl; Sleep(1000); } 初始=0 Call back function 要寫入的資料 Overlapped 結構
// Step 5: 等待 I/O 完成 (你必須使用 WaitForSingleObjectEx 等待, CallBack function 才會被呼叫) /* HANDLE hEvent=CreateEvent( NULL, // no security attributes FALSE, // auto-reset event object FALSE, // initial state is nonsignaled NULL); // unnamed object WaitForSingleObjectEx(hEvent,INFINITE,TRUE); */ // 當 CallBack function 完成時, 會自動 return SleepEx(INFINITE,TRUE); CloseHandle(hFile); cout << "主程式離開" << endl; getchar(); return 0; }
Call Back Function // 當非同步寫入完成時且主程式進入 alerable 狀態, 會呼叫 call back fucntion VOID CALLBACK IoCompletionRoutine(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped) { // If an I/O error occurs, display the error and exit. if (dwErrorCode) { printf("FATAL I/O Error %ld I/O Context %lx.%lx\n", dwErrorCode, lpOverlapped, lpOverlapped->hEvent); ShowError(); ExitProcess(dwErrorCode); } MessageBox(NULL,_T("寫入完成"),_T("Message"),MB_OK); for(int i=0;i<10;i++) Sleep(1000); LocalFree(lpOverlapped); }
Asynchronous Read • 使用 ReadFileEx • 檔案存取必須是 sector size的整數倍 • 讀寫動作的記憶體位址必須為 sector size 的整數倍 得到磁碟的 sector size DWORD SectorsPerCluster,BytesPerSector,NumberOfFreeClusters,TotalNumberOfClusters; GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector, &NumberOfFreeClusters,&TotalNumberOfClusters); Sector size char *buffer=(char*) VirtualAlloc(NULL,BytesPerSector, MEM_COMMIT,PAGE_READWRITE); 會幫我們自動作 aligned
程式的流程 Step 1: CreateFile Step 2: 配置 Overlapped 結構空間 Step 3: 設定要讀取資料位置 1. 讀取 sector size 2. 配置 buffer 存放記憶體 3. 執行讀取資料的動作
int main(int argc, _TCHAR* argv[]){ HANDLE hFile; hFile = CreateFile("c:\\myfile.txt", // open myfile.txt GENERIC_READ, // open for reading 0, // do not share NULL, // no security OPEN_EXISTING, // existing file only FILE_FLAG_OVERLAPPED, NULL); // no attr. template if(hFile== INVALID_HANDLE_VALUE) ShowError(); // Step 1: 配置 Overlapped 結構 空間 LPOVERLAPPED Overlapped; Overlapped =(LPOVERLAPPED) LocalAlloc(LMEM_ZEROINIT, sizeof(OVERLAPPED)); if(!Overlapped){ ShowError(); return -1; } // Step 2: 設定要讀取資料位置 Overlapped->Offset = 0; // 設定起始讀取指標(low word) Overlapped->OffsetHigh = 0; // 起始讀取指標(high word)
// 1. 存取檔案的大小是 sector size 的整數倍 (使用 GetDiskFreeSpace) DWORD SectorsPerCluster,BytesPerSector,NumberOfFreeClusters,TotalNumberOfClusters; GetDiskFreeSpace(NULL,&SectorsPerCluster,&BytesPerSector, &NumberOfFreeClusters,&TotalNumberOfClusters); // 2. 讀寫動作的記憶體位址必須為 sector size 的整數倍 (使用 VirtualAlloc) char *buffer=(char*) VirtualAlloc(NULL,BytesPerSector,MEM_COMMIT,PAGE_READWRITE); // 3. 執行讀取資料的動作 while(ReadFileEx(hFile,buffer,BytesPerSector,Overlapped,IoCompletionRoutine)!=0){ if(GetLastError() != ERROR_SUCCESS){ ShowError(); return -1; } SleepEx(INFINITE,TRUE); } // 4. 釋放記憶體 VirtualFree(buffer,0,MEM_RELEASE); 完整範例: AsynchronousReadDemo