异步IO之----APC

主题:使用ReadFileEx和WriteFileEx实现复制文件的功能。

1.GetThreadIOPendingFlag:这个函数的功能是检查线程还有没有未完成的IO在底层等待处理,这个等待处理和APC队列中是否还有未处理的项是没有关系的。

下面是我的理解:当这个函数返回值说明没有IO处于pending状态时,表明所有文件的读取操作驱动程序都完成且都投递了对应的APC项到所在线程。

2.只要APC开始执行,可定会将队列清空才回让等待函数返回。

// test.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"
#include <assert.h>

struct XOVERLAPPED:OVERLAPPED
{
	BYTE* pBuf;
	HANDLE hFile;
	XOVERLAPPED()
	{
		pBuf = new BYTE[bufsize];
		assert(pBuf);
		this->OffsetHigh = 0;
		count++;
	}
	~XOVERLAPPED()
	{
		delete []pBuf;
		count--;
	}
	static const int bufsize = 1024*1024*4;
	static int count;
	static int max_count;
};
int XOVERLAPPED::count = 0;
int XOVERLAPPED::max_count = 50;

VOID __stdcall WriteCompl(
    __in    DWORD dwErrorCode,
    __in    DWORD dwNumberOfBytesTransfered,
    __inout LPOVERLAPPED lpOverlapped
    )
{
	if(dwErrorCode != ERROR_SUCCESS){
		printf("Write Error APC\n");
	}
	delete static_cast<XOVERLAPPED*>(lpOverlapped);
}

VOID __stdcall ReadCompl(
    __in    DWORD dwErrorCode,
    __in    DWORD dwNumberOfBytesTransfered,
    __inout LPOVERLAPPED lpOverlapped
    )
{
	if(dwErrorCode != ERROR_SUCCESS){
		printf("error\n");
		return;
	}
	XOVERLAPPED* plapped = static_cast<XOVERLAPPED*>(lpOverlapped);
	BOOL ret = WriteFileEx(plapped->hFile, plapped->pBuf, dwNumberOfBytesTransfered, lpOverlapped, WriteCompl);
	if(ret != 0)
		return;
	else{
		printf("WriteFileEx Error\n");
		return;
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	HANDLE hr = ::CreateFile(L"xx.ISO", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
	HANDLE hw = ::CreateFile(L"b.dll", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);
	LARGE_INTEGER file_size = {0};
	BOOL ret;
	ret = SetFilePointerEx(hr, file_size, &file_size, FILE_END);
	ret = SetFilePointerEx(hw, file_size, NULL, FILE_BEGIN);
	XOVERLAPPED* plapped;
	DWORD i;
	SYSTEMTIME time_start, time_end;
	GetSystemTime(&time_start);
	for(i = 0; i < file_size.LowPart; i+=plapped->bufsize){
		plapped = new XOVERLAPPED;
		plapped->hFile = hw;
		plapped->Offset = i;
		ret = ReadFileEx(hr, plapped->pBuf, plapped->bufsize, plapped, ReadCompl);
		if(ret == 0)
			printf("error read\n");
		if(plapped->count == plapped->max_count){
			SleepEx(0, TRUE);//for execute APC
		}
	}
	//下面这个循环式为了判断IO是否全都完成,睡眠0秒的作用是为了去调用apc的
	while(true){
		BOOL ret1 = GetThreadIOPendingFlag(GetCurrentThread(), &ret);
		if(ret1 != 0){
			if(ret == TRUE)
				SleepEx(0, TRUE);
			else{
				SleepEx(0, TRUE);
				break;
			}
		}
	}
	CloseHandle(hr);
	CloseHandle(hw);
	GetSystemTime(&time_end);
	int minute, second;
	minute = time_end.wMinute - time_start.wMinute;
	if(time_end.wSecond >= time_start.wSecond)
		second = time_end.wSecond - time_start.wSecond;
	else{
		second = time_end.wSecond - time_start.wSecond + 60;
		minute--;
	}
	printf("%d:%d",minute, second); 
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值