首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > windows >

Windows 异步IO跟 完成端口(IOCP)

2012-08-07 
Windows 异步IO和 完成端口(IOCP) 见过网上好多的完成端口和网络通信的文章,呵呵,这里就简单的说说文件异

Windows 异步IO和 完成端口(IOCP)

 

见过网上好多的完成端口和网络通信的文章,呵呵,这里就简单的说说文件异步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;}


 

热点排行