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 timeout
Sleep(1); //make sure thread function have run to WaitForSingleObjectEx function.
QueueUserAPC(APCFunc,hThread,NULL); //(2)will IO completed
//SetEvent(hEvent); // (3)will signaled
WaitForSingleObject( hThread, INFINITE );
CloseHandle(hThread);
CloseHandle(hEvent);
}
void main()
{
//DeviceObject();
//getchar();
//TrrigEvent();
//getchar();
AlertableIO();
getchar();
}