概述
见过网上好多的完成端口和网络通信的文章,呵呵,这里就简单的说说文件异步IO和完成端口,这里仅仅说说读取操作。下面是一些总结,很少有人提及,认真的看过MSDN文档之后得出的,欢迎指正。
- 要对文件异步IO操作,需要在文件创建的时候指定FILE_FLAG_OVERLAPPED属性的;
- 异步ReadFileEx是不能读取和IO完成端口绑定的文件句柄的;
- 异步ReadFileEx对OVERLAPPED的hEvent忽视;
- 异步完成后可以出发回调,回调接口需要指定WINAPI属性,实际上就是_stdcall,如果不指定则默认是_cdecl属性,回调完成后,会崩溃的;
- 最后需要等待。
这里简单的附上一段异步代码:
#include <process.h>
#include <Windows.h>
VOID WINAPI rt(
__in DWORD dwErrorCode,
__in DWORD dwNumberOfBytesTransfered,
__inout LPOVERLAPPED lpOverlapped
)
{
printf("rt call backn");
}
int _tmain(int argc, _TCHAR* argv[])
{
OVERLAPPED *ol = new OVERLAPPED;
memset(ol, 0, sizeof *ol);
HANDLE file = CreateFile("ReadMe.txt",
GENERIC_READ,
0,
NULL,
OPEN_EXISTING ,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED ,
NULL);
if(file == INVALID_HANDLE_VALUE)
{
goto mem_free1;
}
size_t buf_len = 1024;
char *buf = new char[buf_len];
if(!buf)
{
goto mem_free1;
}
if(!ReadFileEx(file, buf, buf_len, ol, rt))
{
goto mem_free;
}
SleepEx(INFINITE, TRUE);
mem_free:
delete []buf;
mem_free1:
delete ol;
CloseHandle(file);
return 0;
}
对于ReadFile,主线程在触发异步操作之后,就需要有另外的线程来做辅助工作,可以使用event事件,这里主要介绍完成端口,没有多少好说的,也贴上代码吧:
#include <process.h>
#include <windows.h>
//创建一个IO完成端口
HANDLE CreateNewCompletionPort(DWORD dwNumberOfConcurrentThreads)
{
return( CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, dwNumberOfConcurrentThreads));
}
//将设备与完成端口管理起来
BOOL AssociateDeviceWithCompletionPort(HANDLE hCompletionPort, HANDLE hDevice, DWORD dwCompletionKey)
{
HANDLE h = CreateIoCompletionPort(hDevice, hCompletionPort, dwCompletionKey, 0);
return (h == hCompletionPort);
}
void reader(void *in)
{
HANDLE port = (HANDLE)in;
DWORD rcv_len = 0;
ULONG_PTR my_key = 0;
OVERLAPPED *ol1 = NULL;
while(1)
{
if(!GetQueuedCompletionStatus(port, &rcv_len, &my_key, &ol1, INFINITE))
{
int err = GetLastError();
continue;
}
else
{
_endthread();
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int key = 12345;
HANDLE port = CreateNewCompletionPort(4);
if(!port)
{
int err = GetLastError();
return 0;
}
HANDLE file = CreateFile("ReadMe.txt",
GENERIC_READ,
0,
NULL,
OPEN_EXISTING ,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED ,
NULL);
if(file == INVALID_HANDLE_VALUE)
{
CloseHandle(port);
}
OVERLAPPED *ol = new OVERLAPPED;
memset(ol, 0, sizeof *ol);
if(!AssociateDeviceWithCompletionPort(port, file, key))
{
int err = GetLastError();
CloseHandle(port);
CloseHandle(file);
delete ol;
return 0;
}
int buf_len = 1000;
char *buf = new char[buf_len];
if(!buf)
{
CloseHandle(port);
CloseHandle(file);
delete ol;
return 0;
}
HANDLE h_thread = (HANDLE)_beginthread(reader, 0, port);
if(!ReadFile(file, buf, buf_len, NULL, ol))
{
int err = GetLastError();
if(err != ERROR_IO_PENDING)
{
CloseHandle(port);
CloseHandle(file);
delete ol;
WaitForSingleObject(h_thread, INFINITE);
return 0;
}
}
WaitForSingleObject(h_thread, INFINITE);
CloseHandle(port);
CloseHandle(file);
delete ol;
delete []buf;
return 0;
}
最后
以上就是明亮水池为你收集整理的Windows 异步IO和 完成端口(IOCP)的全部内容,希望文章能够帮你解决Windows 异步IO和 完成端口(IOCP)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复