版权声明: https://blog.csdn.net/dashoumeixi/article/details/83514879
APC简介:APC
第一个例子. 第二个例子使用APC 来解决一些问题
/*
首先使用 OVERLAPPED 结构, 其中有Event 对象, 可用可不用,这个例子先不用
CreateFile 其中一个参数使用 FILE_FLAG_OVERLAPPED
ReadFile 默认同步, 在最后一个参数使用 OVERLAPPED ;
ReadFile 返回TRUE ,则代表已经读完了
否则应该检查 GetLastError , 系统是否为此安排了等待.
如果 GetLastError == ERROR_IO_PENDING ,则成功了, 等着取数据, 否则失败
之后可以使用 GetOverlappedResult(最后一个参数为TRUE) / WaitForSingObject 来等待直到完成;
*/
void read_overlapped(const TCHAR * path)
{
//这里没有使用其中的 Event 对象.
OVERLAPPED overlap = {0};
DWORD bytesReaded = 0;
BOOL ret = FALSE;
char * buf = new char[8196 * 10];
// 注意:FILE_FLAG_OVERLAPPED
HANDLE hFile = CreateFile(path,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
if(INVALID_HANDLE_VALUE == hFile){
cout << "INVALID_HANDLE_VALUE" << endl;
return;
}
//从哪开始读文件
overlap.Offset = 0;
//注意overlap 需要传入
ret = ReadFile(hFile,buf,8196*10,&bytesReaded
,&overlap);
//直接就完成了, 您的计算机硬盘可真快
if(ret){
cout << "done :" << bytesReaded << endl;
cout << buf << endl;
}
else
{
//检测一下错误, 确认是否已经进入准备状态
DWORD err = GetLastError();
//ok
if(ERROR_IO_PENDING == err )
{
//GetOverlappedResult(hFile,&overlap,&bytesReaded,TRUE); 相当于WaitForSingObject
//这样其实不太好 , 浪费cpu.
while(1){
cout << "LOADing: " << GetLastError() << endl;
ret = GetOverlappedResult(hFile,&overlap,&bytesReaded,FALSE);
if(ret){
cout << "ret:" << ret << ",bytesread:" << bytesReaded << endl;
break;
}
}
}
else
{
cout << "err : " << err << endl;
}
}
CloseHandle(hFile);
}
通过OVERLAPPED 中的事件对象,对同一个文件读取多次 .
void read_overlapped2(const TCHAR * path)
{
HANDLE event_handles[2];
OVERLAPPED overlap[2] = {0};
char * buf[2] = {0};
DWORD num = 0;
HANDLE hFile = CreateFile(path,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
if(INVALID_HANDLE_VALUE == hFile){
cout << "INVALID_HANDLE_VALUE" << endl;
return;
}
BOOL ret = 0;
int success_len = 0;
for(int i = 0; i < 2; ++i){
event_handles[i] = CreateEvent(0,TRUE,FALSE,NULL);
overlap[i].hEvent = event_handles[i];
overlap[i].Offset = i*1000 + i;
buf[i] = new char[8196 * 1024];
ret = ReadFile(hFile,buf[i],8196 +overlap[i].Offset ,&num,&overlap[i]);
if(ret){
cout << "index:" << i << ", is done" << endl;
cout << "index:" << i << ",num:" << num;
cout << "index:" << i << buf[i] << endl;
++success_len;
}
else {
if(GetLastError() != ERROR_IO_PENDING){
cout << "index:" << i << "failed" << endl;
delete[] buf[i];
SetEvent(event_handles[i]);
}
else {
++success_len;
}
}
}
cout << "success_len:" << success_len << endl;
WaitForMultipleObjects(success_len,event_handles,TRUE,-1);
ret = GetOverlappedResult(hFile,&overlap[0],&num,FALSE);
cout << "ret:" << ret << ", num:" << num << endl;
ret = GetOverlappedResult(hFile,&overlap[1],&num,FALSE);
cout << "ret:" << ret << ", num:" << num << endl;
CloseHandle(hFile);
}
使用ReadFileEx APC:
const int count = 2;
HANDLE event_io;
void CALLBACK ioCompletionRoutine(
_In_ DWORD dwErrorCode,
_In_ DWORD dwNumberOfBytesTransfered,
_Inout_ LPOVERLAPPED lpOverlapped
)
{
int index = (int)lpOverlapped->hEvent;
printf("index : %d , readbytes: %d ,err:%d\n", index, dwNumberOfBytesTransfered, dwErrorCode);
if (++index == count){
SetEvent(event_io);
}
}
void test_readfileex(const TCHAR * path)
{
event_io = CreateEvent(0, TRUE, FALSE, 0);
const int bufsize = 2 << 13;
HANDLE hFile =CreateFile(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED, NULL);
if (INVALID_HANDLE_VALUE == hFile){
printf("createfile failed");
return;
}
OVERLAPPED overlap[count] = { 0 };
TCHAR* buf[count] = { 0 };
DWORD ret = 0 , err = 0;
for (int i = 0; i <count; ++i){
overlap[i].hEvent = (HANDLE)i;
overlap[i].Offset = i *bufsize + i;
buf[i] = new TCHAR[bufsize];
ret = ReadFileEx(hFile, buf[i], bufsize, &overlap[i], ioCompletionRoutine);
err = GetLastError();
printf("ret:%d, err:%d\n", ret, err);
if (!ret){
// 出错了
}
}
while (1){
//注意是带ex结尾的 . 这里将阻塞ioCompletionRoutine 完成后将返回一次,所以需要判断
ret = WaitForSingleObjectEx(event_io, -1, TRUE);
if (WAIT_OBJECT_0 == ret)
break;
else
printf("WaitForSingleObjectEx return :%d\n", ret);
}
CloseHandle(hFile);
CloseHandle(event_io);
for (int i = 0; i < count; ++i)
delete[] buf[i];
}