Windows 核心编程之10 IO完成端口

下面是创建IO完成端口的函数

//创建一个IO完成端口
HANDLE CreateNewCompletionPort(DWORD NumberOfConcurrentThreads )
{
	return ( CreateIoCompletionPort(INVALID_HANDLE_VALUE,
		NULL,0, NumberOfConcurrentThreads ));
}

//将设备与IO端口关联起来
BOOL AssociateDeviceWithCompletionPort(HANDLE hCompletionPort, HANDLE hDevice,
									   DWORD dwCompletionKey)
{
	//参数2不为NULL,那么参数4忽略
	HANDLE h = CreateIoCompletionPort(hDevice, hCompletionPort,dwCompletionKey,0);

	return (h == hCompletionPort);
}


IO完成端口有5个基础的数据结构:

1 设备列表 包含关联的设备

2 IO完成队列(先入先出)IO请求完成,或者Post一个IO完成请求

3 以释放线程 (后入先出)从等待线程唤醒处理IO完成请求,或者暂停的线程被唤醒

4 以等待线程  已经释放的线程如果等待了,那么进入等待线程列表

5 以暂停线程 释放的被暂停



向设备发出IO请求,但不把该项的已完成的IO请求添加到IO队列去,是可以的,具体方法是:

Overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE,NULL);

Overlapped.hEvent = (HANDLE) ((DWOR_PTR)Overlapped.hEvent | 1 );

ReadFile(...,&Overlapped);


关闭这个事件句柄时不要忘记最低位清掉

CloseHandle((Handle)((DWORD_PTR)Overlapped.hEvent & ~1) );


#include <windows.h>
#include <stdio.h>
#include <process.h>

#define COMPLETION_KEY_READ		1
#define COMPLETION_KEY_WRITE	2

typedef struct MyData : public OVERLAPPED
{
	LPTSTR m_lpBuffer;
	LONG m_bufferSize;
	MyData()
	{
		Internal = InternalHigh = 0 ;
		Offset = OffsetHigh = 0;
		this->hEvent = NULL;
	}

}MYDATA;

long g_fileSize = 0;
LONG lReadcount = 0;
LONG lWritecount = 0;
HANDLE g_hFileRead,g_hFileWrite;



MYDATA data1,data2;

unsigned WINAPI ThreadFunc(LPVOID lp)
{
	HANDLE hIO = (HANDLE)lp;
	ULONG_PTR comKey = 0;

	LPOVERLAPPED plov = NULL;
	MYDATA* pData = NULL;

	long filereadSize = 0;
	DWORD dw;
	const long bufferSize = 4*1024;


	while(lReadcount > 0 || lWritecount > 0 )
	{
		BOOL bok = GetQueuedCompletionStatus(hIO, &dw,&comKey,(LPOVERLAPPED*) &pData, INFINITE);

		switch(comKey)
		{
		case COMPLETION_KEY_READ:
			lReadcount--;
			WriteFile(g_hFileWrite, pData->m_lpBuffer, bufferSize, &dw, pData);
			lWritecount++;
			break;
		case COMPLETION_KEY_WRITE:
			lWritecount--;
			if(filereadSize >= g_fileSize)
				break;
			lReadcount++;

			pData->Offset = filereadSize;
			pData->OffsetHigh = 0;
			ReadFile(g_hFileRead,pData->m_lpBuffer, bufferSize, &dw, pData);
			filereadSize += bufferSize;
			break;
		default:
			break;
		}
	}

	CloseHandle(g_hFileRead);
	CloseHandle(g_hFileWrite);

	HANDLE hFile = CreateFile(L"2.txt", GENERIC_WRITE, 
		0, NULL, OPEN_EXISTING, 0, NULL);
	LARGE_INTEGER ll;
	ll.QuadPart = g_fileSize;

	SetFilePointerEx(hFile,ll,NULL,FILE_BEGIN);
	SetEndOfFile(hFile);
	
	return 0;
}



int main()
{
	HANDLE hIoCp = CreateIoCompletionPort(INVALID_HANDLE_VALUE,0,0,0);
	g_hFileRead = CreateFile(TEXT("1.txt"),GENERIC_ALL,0,NULL, OPEN_ALWAYS,FILE_FLAG_OVERLAPPED,
		NULL);
	g_hFileWrite = CreateFile(TEXT("2.txt"), GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_FLAG_OVERLAPPED,
		NULL);
	LARGE_INTEGER lagerFile;

	GetFileSizeEx(g_hFileRead, &lagerFile);
	g_fileSize = lagerFile.QuadPart;

	if(CreateIoCompletionPort(g_hFileRead, hIoCp, COMPLETION_KEY_READ, 0) != hIoCp)
	{
		return GetLastError();
	}

	if (CreateIoCompletionPort(g_hFileWrite, hIoCp, COMPLETION_KEY_WRITE, 0) != hIoCp)
	{
		return GetLastError();
	}


	data1.m_bufferSize = 4 * 1024;
	data1.m_lpBuffer =(LPTSTR) VirtualAlloc(NULL, data1.m_bufferSize, MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);

	data2.m_bufferSize = data1.m_bufferSize;
	data2.m_lpBuffer = (LPTSTR) VirtualAlloc(NULL, data2.m_bufferSize, MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);


	PostQueuedCompletionStatus(hIoCp, 0, COMPLETION_KEY_WRITE, &data1);
	PostQueuedCompletionStatus(hIoCp, 0, COMPLETION_KEY_WRITE, &data2);
	lWritecount = 2;

	HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadFunc, hIoCp, 0, NULL);

	WaitForSingleObject(hThread,INFINITE);


	CloseHandle(hIoCp);

	system("pause");


//	getchar();

	return 0;
}


你可能感兴趣的:(C++,windows,Win32,线程,IO完成端口)