见过网上好多的完成端口和网络通信的文章,呵呵,这里就简单的说说文件异步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 back\n");
}
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下IOCP模型 socket服务器端实例 1. 创建服务器socket, 并将socket设置为非阻塞模式 2. bind()绑定IP地此与端口 3. listen() 4. 创建IO完成端口,将socket绑定到IO完成端口上 5. 根据当前机器CPU个数创建工作...
C# 完成端口 IOCP 输入输出完成端口(Input/Output Completion Port,IOCP), 是支持多个同时发生的异步I/O操作的应用程序编程接口。
一个IOCP的示例,封装了IO完成端口的IO模型。可以用做学习参考,也可以直接使用其中封装的类。-a IOCP example, the complete package, IO port IO model. Learning can be used as reference, which can be used ...
新手学习iocp的好例子~MFC下的完成端口IOCP源码学习线程池与完成端口的朋友可参考参考
MFC下的完成端口IOCP源码 学习线程池与完成端口的朋友可参考参考。
完成端口 IOCP+UDP的架构,代码为C++在 vs2015下编写的.
重叠iO和完成端口模型
完成端口IOCP Socket DELPHI控件
windows完成端口IOCP SOCKET TCP服务器 源代码.zip
完成端口IOCP稳定程序,异步接受连接请求,带有定时发送数据线程
简单的完成端口IOCP服务器源码,完整展示IOCP的运行方式.
C++ IOCP文档:别人的帖子,整理了一下
最近有项目要做一个高性能网络服务器,决定下功夫搞定完成端口(IOCP),最终花了一个星期终于把它弄清楚了,并用C++写了一个版本,效率很不错。 但,从项目的总体需求来考虑,最终决定上.net平台,因此又花了一天...
用完成端口IOCP实现的socket服务端引擎和多线程客户端引擎.zip
1、在C#中,不用去面对完成端口的操作系统内核对象,Microsoft已经为我们提供了SocketAsyncEventArgs类,它封装了IOCP的使用。请参考:...
完成端口IOCP稳定程序(修正部分内存释放不合理的地方)
把完成端口IOCP封装成DLL.zip
一个很好用的完成端口类,效率超高。欢迎下载。
所有接口均使用异步回调的方式处理,内部实现使用Windows下性能最高的IOCP完成端口网络模型,并很好地处理了多线程安全和同步问题。 线程创建和事件信号量等地方用到了MFC的类,如果项目不支持MFC,可以把这些地方...
完成端口 IOCP+UDP的架构,代码为C++在 vs2015下编写的.