Windows核心编程:第10章 同步设备IO与异步设备IO
Github
https://github.com/gongluck/Windows-Core-Program.git
//第10章 同步设备IO与异步设备IO.cpp: 定义应用程序的入口点。
//
#include "stdafx.h"
#include "第10章 同步设备IO与异步设备IO.h"
//可提醒IO回调
VOID WINAPI funComplete(
	_In_    DWORD dwErrorCode,
	_In_    DWORD dwNumberOfBytesTransfered,
	_Inout_ LPOVERLAPPED lpOverlapped
)
{
}
//IO完成端口工作线程
DWORD WINAPI workthread(LPVOID lpThreadParameter)
{
	DWORD NumberOfBytesTransferred;
	DWORD CompletionKey;
	OVERLAPPED* pOverlapped;
	BOOL bres = GetQueuedCompletionStatus(lpThreadParameter, &NumberOfBytesTransferred, &CompletionKey, &pOverlapped, INFINITE);
	//GetQueuedCompletionStatusEx可获取多个IO请求结果
	DWORD dres = GetLastError();
	return 0;
}
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
	//打开(创建)文件
	HANDLE hFile = CreateFile(TEXT("第10章 同步设备IO与异步设备IO.cpp"), GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		MessageBox(nullptr, TEXT("打开文件失败!"), TEXT("error"), MB_OK);
		return 0;
	}
	//文件类型
	DWORD dres = GetFileType(hFile);
	//dres == FILE_TYPE_DISK
	//文件大小
	LARGE_INTEGER li;
	BOOL bres = GetFileSizeEx(hFile, &li);//逻辑大小
	li.LowPart = GetCompressedFileSize(TEXT("第10章 同步设备IO与异步设备IO.cpp"), (DWORD*)&li.HighPart);//物理大小
	//文件指针
	li.QuadPart = 0;
	bres = SetFilePointerEx(hFile, li, nullptr, FILE_END);
	bres = SetFilePointerEx(hFile, li, &li, FILE_CURRENT);
	bres = SetEndOfFile(hFile);
	li.QuadPart = 0;
	bres = SetFilePointerEx(hFile, li, nullptr, FILE_BEGIN);
	//同步IO
	char* buf = new char[100];
	bres = ReadFile(hFile, buf, 100, &dres, nullptr);
	delete []buf;
	buf = nullptr;
	//刷新缓冲区
	bres = FlushFileBuffers(hFile);
	//CancelSynchronousIo
	//取消线程未完成的同步IO请求
	//关闭文件
	CloseHandle(hFile);
	hFile = nullptr;
	//异步IO
	HANDLE hFile2 = CreateFile(TEXT("第10章 同步设备IO与异步设备IO.cpp"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, nullptr);
	OVERLAPPED ol;
	ol.Offset = 1024;
	ol.OffsetHigh = 0;
	ol.hEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
	char* buf2 = new char[1024];
	bres = ReadFile(hFile2, buf2, 1024, nullptr, &ol);//异步方式总是返回FALSE
	dres = GetLastError();
	switch (dres)
	{
	case ERROR_IO_PENDING:
		//IO请求添加成功
		//WaitForSingleObject(hFile2, INFINITE);
		WaitForSingleObject(ol.hEvent, INFINITE);
		break;
	case ERROR_INVALID_USER_BUFFER:
	case ERROR_NOT_ENOUGH_MEMORY:
		break;
	case ERROR_NOT_ENOUGH_QUOTA:
		break;
	default:
		break;
	}
	//取消队列中的IO请求
	//bres = CancelIo(hFile2);
	bres = CancelIoEx(hFile2, &ol);
	//bres = CancelIoEx(hFile2, nullptr);
	//bres = CloseHandle(hFile2);
	if (ol.hEvent != nullptr)
	{
		CloseHandle(ol.hEvent);
		ol.hEvent = nullptr;
	}
	//可提醒IO
	OVERLAPPED ol2;
	ol2.Offset = 1024;
	ol2.OffsetHigh = 0;
	ol2.hEvent = nullptr;
	dres = ReadFileEx(hFile2, buf2, 1024, &ol2, funComplete);//回调函数在同一个线程空间
	//置为可提醒状态
	//APC队列中只要有一个,线程就不会进入睡眠
	dres = SleepEx(INFINITE, TRUE);
	//WaitForSingleObjectEx
	//WaitForMultipleObjectsEx
	//SignalObjectAndWait
	//GetQueuedCompletionStatusEx
	//MsgWaitForMultipleObjectsEx
	dres = GetLastError();//WAIT_IO_COMPLETION
	//手动添加一项到APC队列
	//可以让目标线程结束睡眠
	dres = QueueUserAPC((PAPCFUNC)funComplete, GetCurrentThread(), NULL);
	//IO完成端口
	HANDLE iocp = CreateIoCompletionPort(hFile2, nullptr, 1, 2);
	HANDLE hts[2];
	for (int i = 0; i < 2; ++i)
		hts[i] = CreateThread(nullptr, 0, workthread, iocp, 0, nullptr);
	bres = PostQueuedCompletionStatus(iocp, 100, 1, &ol); //模拟发送IO请求完成
	bres = ReadFile(hFile2, buf2, 1024, nullptr, &ol2);
	dres = GetLastError();
	WaitForMultipleObjects(2, hts, TRUE, INFINITE);
	for (int i = 0; i < 2; ++i)
	{
		CloseHandle(hts[i]);
		hts[i] = nullptr;
	}
	CloseHandle(iocp);
	iocp = nullptr;
	CloseHandle(hFile2);
	hFile2 = nullptr;
	delete[]buf2;
	buf2 = nullptr;
	system("pause");
	return 0;
}
Windows核心编程:第10章 同步设备IO与异步设备IO的更多相关文章
- windows核心编程 第8章201页旋转锁的代码在新版Visual Studio运行问题
		// 全局变量,用于指示共享的资源是否在使用 BOOL g_fResourceInUse = FALSE; void Func1() { //等待访问资源 while(InterlockedExcha ... 
- windows核心编程 第5章job lab示例程序 解决小技巧
		看到windows核心编程 第5章的最后一节,发现job lab例子程序不能在我的系统(win8下)正常运行,总是提示“进程在一个作业里” 用process explorer程序查看 ... 
- windows核心编程---第七章 用户模式下的线程同步
		用户模式下的线程同步 系统中的线程必须访问系统资源,如堆.串口.文件.窗口以及其他资源.如果一个线程独占了对某个资源的访问,其他线程就无法完成工作.我们也必须限制线程在任何时刻都能访问任何资源.比如在 ... 
- 《Windows核心编程》第九章——用内核对象进行线程同步
		先举一个有bug的例子: #include <iostream> #include <windows.h> #include <process.h> using n ... 
- Windows核心编程 第十一章 线程池的使用
		第11章 线程池的使用 第8章讲述了如何使用让线程保持用户方式的机制来实现线程同步的方法.用户方式的同步机制的出色之处在于它的同步速度很快.如果关心线程的运行速度,那么应该了解一下用户方式的同步机制是 ... 
- Windows核心编程 第七章 线程的调度、优先级和亲缘性(下)
		7.6 运用结构环境 现在应该懂得环境结构在线程调度中所起的重要作用了.环境结构使得系统能够记住线程的状态,这样,当下次线程拥有可以运行的C P U时,它就能够找到它上次中断运行的地方. 知道这样低层 ... 
- Windows核心编程 第27章 硬件输入模型和局部输入状态
		第27章 硬件输入模型和局部输入状态 这章说的是按键和鼠标事件是如何进入系统并发送给适当的窗口过程的.微软设计输入模型的一个主要目标就是为了保证一个线程的动作不要对其他线程的动作产生不好的影响. 27 ... 
- Windows核心编程 第十七章 -内存映射文件(下)
		17.3 使用内存映射文件 若要使用内存映射文件,必须执行下列操作步骤: 1) 创建或打开一个文件内核对象,该对象用于标识磁盘上你想用作内存映射文件的文件. 2) 创建一个文件映射内核对象,告诉系统该 ... 
- Windows核心编程 第六章 线程基础知识 (上)
		第6章 线程的基础知识 理解线程是非常关键的,因为每个进程至少需要一个线程.本章将更加详细地介绍线程的知识.尤其是要讲述进程与线程之间存在多大的差别,它们各自具有什么作用.还要介绍系统如何使用线程内核 ... 
- Windows核心编程 第三章 内核对象
		第3章内核对象 在介绍Windows API的时候,首先要讲述内核对象以及它们的句柄.本章将要介绍一些比较抽象的概念,在此并不讨论某个特定内核对象的特性,相反只是介绍适用于所有内核对象的特性. 首先介 ... 
随机推荐
- C#设计模式(4)——抽象工厂模式(Abstract Factory)
			简单工厂模式: 简单工厂模式的工厂类随着产品类的增加需要增加额外的代码 工厂方法模式: 工厂方法模式每个具体工厂类只完成单个实例的创建,所以它具有很好的可扩展性 但是在实际应用中,一个工厂不止会创建单 ... 
- hadoop distcp hdfs://ns1/aaa hdfs://ns8/bbb UnknownHostException: xxx 两个高可用(ha)集群间distcp 如何识别两个集群逻辑名称
			在要执行distcp 的客户端配置添加 dfs.internal.nameservices 指local service 就是client 所在的hadoop 的逻辑名称 <!-- servic ... 
- TCARS: Time- and Community-Aware Recommendation  System(时间感知和社区感知推荐系统)
			随着用户在物品上产生了大量行为,推荐系统成为了线上系统的重要组成部分.推荐系统算法使用用户对物品的行为信息以及上下文数据为每个用户推荐一组物品.算法根据用户之间及物品之间的相似度建立.本文介绍了一个基 ... 
- python读取excel表
			from xlrd import open_workbookimport re #创建一个用于读取sheet的生成器,依次生成每行数据,row_count 用于指定读取多少行, col_count 指 ... 
- node.js获取本机Ip, hostName, mac
			//获取ip地址 getIPAdress() { let interfaces = require('os').networkInterfaces(); for (var devName in int ... 
- Eurekalog
			Eurekalog E:\Program Files (x86)\Neos Eureka S.r.l\EurekaLog 7\Packages\Studio25\EurekaLogComponent ... 
- postgres on linux red hat 7 配置问题
			记录几个重点的东西吧,具体的步骤 不上了,网上有很多, 1. redhat subscripiton需要订阅,没钱的需要去更换yum 源,也很简单,就是把自带的yum给删掉,重装其他的,大家可以百度 ... 
- ubuntu下搭建svn服务器
			[ubuntu下搭建svn服务器] 1.创建目录 mkdir ~/svn/repository/ 2.创建仓库 svnadmin create repository 3.进入 repository/c ... 
- php-beanstalkd消息队列类分享
			<?php namespace Common\Business; /** * beanstalk: A minimalistic PHP beanstalk client. * * Copyri ... 
- 关于TP5.0搜索后分页
			使用$Model->where($where)->paginate($page,$count);的时候如果点击下一页会出现条件重置问题,经过测试可以使用Db::name('data') - ... 
