异步I/O(1)使用设备内核对象
来源:互联网 发布:淘宝神兽金刚玩具 编辑:程序博客网 时间:2024/06/06 00:42
进行异步I/O的四种方式
1. 使用设备内核对象
2. 使用事件内核对象使用事件内核对象
3. 可提醒I/O可提醒I/O
4. I/O完成端口I/O完成端口
异步I/O的操作过程:
当我们使用异步I/O操作时,我们的程序不会卡死在文件操作的地方.如当我们使用CreateFile打开一个个文件时,它会给操作系统发送一个打开文件的请求然后就直接返回,不会等待文件打开是否成功.此时我们可以进行其他的操作.在操作系统将文件成功打开之后就会发送一个通知.然后就可以去处理文件打开之后的操作.
在进行异步操作时,首先需要将CreateFile的dwFlagsAndAttributes参数设置为FILE_FLAG_OVERLAPPED
在进行异步操作的时候需要使用一个结构体
typedef struct _OVERLAPPED { ULONG_PTR Internal;//保存请求的错误码 ULONG_PTR InternalHigh;//传输成功的字节数 union { struct {//文件开始读写的偏移位置 DWORD Offset; DWORD OffsetHigh; } DUMMYSTRUCTNAME; PVOID Pointer; } DUMMYUNIONNAME; HANDLE hEvent;//事件内核对象,在I/O操作完成之后被激发} OVERLAPPED, *LPOVERLAPPED;
异步I/O的基本操作
//一个文件类class MyFile{public: MyFile(const WCHAR *filePath = L""); ~MyFile(); BOOL OpenFile( _In_ DWORD dwDesiredAccess = GENERIC_READ | GENERIC_WRITE, _In_ DWORD dwShareMode = FILE_SHARE_READ, _In_ DWORD dwCreationDisposition = OPEN_EXISTING, _In_ DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes = nullptr, _In_opt_ HANDLE hTemplateFile = nullptr ); WCHAR *SetFilePath(const WCHAR *filePath); const WCHAR *GetFilePath()const; const LONGLONG GetFileSize()const; const HANDLE GetHandle()const;private: HANDLE m_hFile; WCHAR *m_filePath;};MyFile::MyFile(const WCHAR *filePath):m_hFile(INVALID_HANDLE_VALUE){ SetFilePath(filePath);}MyFile::~MyFile(){ delete[]m_filePath; if (m_hFile != INVALID_HANDLE_VALUE) CloseHandle(m_hFile);}BOOL MyFile::OpenFile( _In_ DWORD dwDesiredAccess, _In_ DWORD dwShareMode, _In_ DWORD dwCreationDisposition, _In_ DWORD dwFlagsAndAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _In_opt_ HANDLE hTemplateFile){ BOOL bRet = TRUE; m_hFile = CreateFileW(m_filePath, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); if(m_hFile == INVALID_HANDLE_VALUE) { bRet = FALSE; throw WinException(GetLastError()); } return bRet;}WCHAR* MyFile::SetFilePath(const WCHAR* filePath){ SIZE_T strLen = wcslen(filePath) + sizeof(WCHAR); m_filePath = new WCHAR[strLen]; wcscpy_s(m_filePath, strLen, filePath); return m_filePath;}const WCHAR* MyFile::GetFilePath() const{ return m_filePath;}const LONGLONG MyFile::GetFileSize()const{ LARGE_INTEGER large_integer = { 0 }; GetFileSizeEx(m_hFile, &large_integer); return large_integer.QuadPart;}const HANDLE MyFile::GetHandle() const{ return m_hFile;}
//一个异常类class WinException{public: WinException(DWORD dwErrorCode); ~WinException(); const WCHAR *What()const;private: DWORD m_dwErrorCode; WCHAR *m_strErrorMsg;};WinException::WinException(DWORD dwErrorCode):m_dwErrorCode(dwErrorCode){ FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, nullptr, m_dwErrorCode, 0, (LPWSTR)(&m_strErrorMsg), 0, nullptr);}WinException::~WinException(){ LocalFree(m_strErrorMsg);}const WCHAR* WinException::What() const{ return m_strErrorMsg;}
//调用过程int main(){ MyFile clsFile(L"a.txt"); clsFile.OpenFile(GENERIC_READ, 0, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED); BYTE buffer[MAXBYTE] = { 0 }; OVERLAPPED overlapped = { 0 }; BOOL bRet = ReadFile(clsFile.GetHandle(), buffer, MAXBYTE, nullptr, &overlapped); DWORD dwError = GetLastError(); if(!bRet && dwError == ERROR_IO_PENDING) { WaitForSingleObject(clsFile.GetHandle(), 10); std::cout << buffer; } return 0;}
阅读全文
1 0
- 异步I/O(1)使用设备内核对象
- 异步I/O 设备内核对象,事件内核对象,可提醒I/O 接收I/O通知
- 异步I/O(2)使用事件内核对象
- 异步设备I/O
- Linux内核开发之异步通知与异步I/O《来自linux设备开发详解》
- 设备I/O之“异步设备I/O请求”
- 【读书笔记】同步设备I/O与异步设备I/O
- 异步设备I/O相关知识
- I/O Concepts(3) : 同步设备I/O 和 异步设备I/O
- 十、同步设备I/O与异步设备I/O(I/O完成端口)
- Linux内核块设备I/O子系统
- linux内核之设备I/O块
- Linux设备驱动中的异步通知与异步I/O
- Linux设备驱动中的异步通知与异步I/O
- linux设备驱动--异步通知和异步I/O
- linux设备驱动之异步通知与异步I/O
- Chapter10-“I/O设备的同步和异步”之异步I/O简介
- Linux设备驱动开发详解-Note(18)---Linux 设备驱动中的异步通知与异步 I/O(1)
- 编程问题
- [翻译]Filters
- 0519 G2n#W2B-B Vicious Keyboard
- 前缀树的JavaScript实现
- c++第六次实验项目3
- 异步I/O(1)使用设备内核对象
- 跨平台获取可执行文件的目录
- 【usaco2017 March Platinum】Modern Art
- 汇编语言 编写程序,如果输入的是大写字母,则输出对应的小写字母;如果输入的是小写字母,则输出对应的大写字母;如果输入的是数字,原样输出;按回车结束
- 贪心法--背包问题(不是0/1背包问题)
- eclipse给JVM设置参数后程序启动失败
- LINUX编译错误总结
- POJ 2115 C Looooops——拓展欧几里得算法
- 汇编语言 将字符串中大写转换为小写 小写转换为大写 数字不变