CreateFile
SetFilePointerEx
SetEndOfFile
FlushFileBuffers 類似FILE_FLAG_WRITE_THROUGH功能
在異步I/O請求完成之前,一定不能移動或是銷毀在發出I/O請求時所使用的數據緩存和OVERLAPPED結構。
BOOL WINAPI CancelIo(
? __in? HANDLE hFile
);
取消同給定句柄所標識的線程添加到隊列中的所有I/O請求(除非該句柄具有與之相關聯的I/O完成端口)
BOOL WINAPI CancelIoEx(
? __in????? HANDLE hFile,
? __in_opt? LPOVERLAPPED lpOverlapped
);
取消指定I/O請求,如lpOverlapped為NULL,取消所有
可置線程為可提醒狀態的函數:
SleepEx/WaitForSingleObjectEx/WaitForMultipleObjectsEx/SignalObjectAndWait/GetQueuedCompletionStatusEx/MsgWaitForMultipleObjectsEx
bAlertable 為TRUE, 不帶Ex的函數實際是調用Ex并傳入FLASE。
調用這6個函數,系統會先檢查APC隊列有沒有項,如有,系統不會讓線程進入睡眠狀態。沒有時才會掛起
當系統創建一個線程的時候,會同時創建一個與線程相關聯的隊列,這個隊列被稱為異步過程調用APC
DWORD WINAPI QueueUserAPC(
? __in? PAPCFUNC pfnAPC,
? __in? HANDLE hThread,
? __in? ULONG_PTR dwData
);
手動加入一項到APC隊列
用來接收I/O完成通知的方法
1.觸發設備內核對象
2.觸發事件內核對象
3.使用可提醒I/O
4.使用I/O完成端口
#include <Windows.h>
#include <stdio.h>
#include <process.h>void DeviceObject()
{//FILE_FLAG_WRITE_THROUGH Instructs the system to write through any intermediate cache and go directly to disk. The system can still cache write operations, but cannot lazily flush them. //FILE_FLAG_DELETE_ON_CLOSE CloseHandle will delete this temp file.HANDLE hFile = CreateFileW(L"c:\\test\\temp.txt",GENERIC_READ|GENERIC_WRITE|FILE_SHARE_DELETE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE|FILE_FLAG_OVERLAPPED,NULL);wchar_t buf[11] = L"1234567890";OVERLAPPED ov = { 0 };ov.Offset = 3;BOOL bWriteDoned = WriteFile(hFile,buf,8*sizeof(wchar_t),NULL,&ov);DWORD dw = GetLastError();if( !bWriteDoned && (dw == ERROR_IO_PENDING) ){wprintf(L"dw == ERROR_IO_PENDING.\n");WaitForSingleObject(hFile, INFINITE);bWriteDoned = TRUE;}if(bWriteDoned){wprintf(L"write over.\n");}else{wprintf(L"other fail.\n");}
}void TrrigEvent()
{HANDLE hFile = CreateFileW(L"c:\\test\\temp.txt",GENERIC_READ|GENERIC_WRITE|FILE_SHARE_DELETE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_TEMPORARY/*|FILE_FLAG_DELETE_ON_CLOSE*/|FILE_FLAG_OVERLAPPED,NULL);wchar_t buf[11] = L"1234567890";OVERLAPPED ovWrite = { 0 };ovWrite.Offset = 3;ovWrite.hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);BOOL bWriteDoned = WriteFile(hFile,buf,8*sizeof(wchar_t),NULL,&ovWrite);BYTE bufRead[20];OVERLAPPED ovRead = { 0 };ovRead.Offset = 6;ovRead.hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);ReadFile(hFile,bufRead,20,NULL,&ovRead);HANDLE hEvent[2] = { ovWrite.hEvent, ovRead.hEvent };bool bWrite = true, bRead = true;do{DWORD dw = WaitForMultipleObjects(2,hEvent,FALSE,INFINITE);switch( dw - WAIT_OBJECT_0 ){case 0:{wprintf(L"Write completed.\n");bWrite = false;break;}case 1:{wprintf(L"Read completed.\n");bRead = false;break;}}}while(bWrite | bRead);
}VOID WINAPI APCFunc(ULONG_PTR dwParam)
{dwParam;
}
unsigned __stdcall ThreadFunc( void* pArguments )
{HANDLE hEvent = (HANDLE)pArguments;//Waits until (1)the specified object is in the signaled state, // (2)an I/O completion routine or asynchronous procedure call (APC) is queued to the thread, // (3)or the time-out interval elapses.DWORD dw = WaitForSingleObjectEx(hEvent,5000,TRUE);switch( dw ){case WAIT_OBJECT_0:{wprintf(L"Event is signaled.\n");break;}case WAIT_IO_COMPLETION:{wprintf(L"IO completed.\n");break;}case WAIT_TIMEOUT:{wprintf(L"timeout.\n");break;}}_endthreadex( 0 );return 0;
} void AlertableIO()
{HANDLE hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);HANDLE hThread = (HANDLE)_beginthreadex( NULL, 0, &ThreadFunc, hEvent, 0, NULL );//; //(1)will timeoutSleep(1); //make sure thread function have run to WaitForSingleObjectEx function.QueueUserAPC(APCFunc,hThread,NULL); //(2)will IO completed//SetEvent(hEvent); // (3)will signaledWaitForSingleObject( hThread, INFINITE );CloseHandle(hThread);CloseHandle(hEvent);
}void main()
{//DeviceObject();//getchar();//TrrigEvent();//getchar();AlertableIO();getchar();
}
?
總結
以上是生活随笔為你收集整理的异步I/O 设备内核对象,事件内核对象,可提醒I/O 接收I/O通知的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。