做网站推销产品效果怎么样,做黑网站吗,合肥专业商业网站,福田做商城网站建设哪家技术好第六章#xff1a;Overlapped I/O#xff0c;在你身后变戏法 1.overlapped I/O 是 Win32 的一项技术#xff0c;你可以要求操作系统为你传送数据#xff0c;并且在传送完毕时通知你。这项技术使你的程序在I/O 进行过程中仍然能够继续处理事务。事实上#xff0c;操作系统内…第六章Overlapped I/O在你身后变戏法 1.overlapped I/O 是 Win32 的一项技术你可以要求操作系统为你传送数据并且在传送完毕时通知你。这项技术使你的程序在I/O 进行过程中仍然能够继续处理事务。事实上操作系统内部正是以线程来完成 overlapped I/O。 2.Win32文件操作函数 1CreateFile可以用来打开文件、串行口和并行口、Named pipes、Console。 HANDLE CreateFile(LPCTSTR lpFileName, // 指向文件名称DWORD dwDesiredAccess, // 存取模式读或写DWORD dwShareMode, // 共享模式share modeLPSECURITY_ATTRIBUTES lpSecurityAttributes, // 指向安全属性结构DWORD dwCreationDisposition, // 如何产生DWORD dwFlagsAndAttributes, // 文件属性HANDLE hTemplateFile // 一个临时文件将拥有全部的属性拷贝); 注overlapped I/O性质可以在同一时间读写文件的许多部分多个overlapped请求执行次序无法保证overlapped I/O的基本型式是以ReadFile和WriteFile完成的。 2ReadFile BOOL ReadFile(HANDLE hFile, // 欲读之文件LPVOID lpBuffer, // 接收数据之缓冲区DWORD nNumberOfBytesToRead, // 欲读取的字节个数LPDWORD lpNumberOfBytesRead, // 实际读取的字节个数的地址LPOVERLAPPED lpOverlapped // 指针指向 overlapped info); 3WriteFile BOOL WriteFile(HANDLE hFile, // 欲写之文件LPCVOID lpBuffer, // 储存数据之缓冲区DWORD nNumberOfBytesToWrite, // 欲写入的字节个数LPDWORD lpNumberOfBytesWritten, // 实际写入的字节个数的地址LPOVERLAPPED lpOverlapped // 指针指向 overlapped info); 如果CreateFile() 的第6个参数被指定为FILE_FLAG_ OVERLAPPED就必须在上述的 lpOverlapped 参数中提供一个指针指向一个 OVERLAPPED 结构。 4OVERLAPPED结构 typedef struct _OVERLAPPED {DWORD Internal; //通常保留。当GetOverlappedResult传回False并且GetLastError并非传回ERROR_IO_PENDING,则内含一个视系统而定的状态。DWORD InternalHigh; //通常被保留当GetOverlappedResult传回True则内含“被传输数据的长度”DWORD Offset; //读、写偏移位置从文件头开始算起。若目标设备不支持文件位置忽略DWORD OffsetHigh; //64位文件偏移中较高32位。若目标设备不支持文件位置忽略HANDLE hEvent; //manual reset eventoverlapped I/O完成时被激发。ReadFileEX,WriteFileEX忽略这个栏位彼时被用来传递一个用户自定义的指针。} OVERLAPPED, *LPOVERLAPPED; OVERLAPPED 结构执行两个重要的功能。第一它像一把钥匙用以识别每一个目前正在进行的 overlapped 操作。第二它在你和系统之间提供了一个共享区域参数可以在该区域中双向传递。 通常overlapped结构存放在heap中。 3.被激发的File Handles 1异步IO的步骤CreateFile指定FILE_FLAG_OVERLAPPED设立一个OVERLAPPED结构调用ReadFile、WriteFile带上这个参数。 2文件handle是一个核心对象一旦操作完毕即被激发。 3GetOverlappedResult BOOL GetOverlappedResult(HANDLE hFile, //文件设备的handleLPOVERLAPPED lpOverlapped, //一个指针指向overlapped结构LPDWORD lpNumberOfBytesTransferred, //一个指针指向DWORD保存真正被传输的字节数。BOOL bWait //是否要等待操作完成TRUE表示等待。); 4虽然你要求一个overlapped 操作但它并不一定就是 overlapped如果数据已经被放进 cache中或如果操作系统认为它可以很快速地取得那份数据那么文件操作就会在ReadFile() 返回之前完成而 ReadFile() 将传回 TRUE。 5一个文件操作为 overlapped而操作系统把“操作请求”放到队列中等待执行 ReadFile() 和、WriteFile()都会传回 FALSE 以示失败。这个行为并不是很直观 你必须调用GetLastError() 并确定它传回 ERROR_IO_PENDING那意味着“overlappedI/O 请求”被放进队列之中等待执行。GetLastError() 也可能传回其他的值例如 ERROR_HANDLE_EOF那就真正代表一个错误了。 4.被激发的event对象 1所使用的 event 对象必须是手动重置manual-reset而非自动重置auto-reset。 2IOBYEVENT例子。 5.异步过程调用Asynchronous Procedure CallsAPCs 1使用overlapped I/O与event搭配的两个问题 1WaitForMultipleObjects最多等待64个对象。 2必须不断的根据“哪一个handle被激发”而计算如何反应。 2使用Ex版的ReadFile和WriteFile可以使用异步过程调用机制。只有当线程处于alertable状态时APCs才会被调用。当线程因为以下5个函数而处于等待状态且线程的“alertable”标记被设为TRUE则线程处于alertable状态 SleepEx WaitForSingleObjectEx WaitForMultipleObjectEx MsgWaitForMultipleObjectsEx SignalObjectAndWait(); 3用于 overlapped I/O 的 APCs 是一种所谓的 user mode APCs。WindowsNT 另有一种所谓的 kernel mode APCs。Kernel mode APCs 也会像 usermode APCs 一样被保存起来但一个 kernel mode APC 一定会在下一个timeslice 被调用不管线程当时正在做什么。 Kernel mode APCs 用来处理系统机能不在应用程序的控制之中。 4提供的 I/O completion routine 应该有这样的型式: VOID WINAPI FileIOCompletionRoutine(DWORD dwErrorCode, //0表示操作完成ERROR_HANDLE_EOF表示操作已经到了文件尾端。DWORD dwNumberOfBytesTransferred,//真正被传输的数据字节数LPOVERLAPPED lpOverlapped//指向overlapped结构此结构由开启overlapped I/O操作的函数提供); 5使用 APCs 时OVERLAPPED 结构中的 hEvent 栏位不需要用来放置一个 event handle。Win32 文件上说此时 hEvent 栏位可以由程序员自由运用。那么最大的用途就是首先配置一个结构描述数据来自哪里或是要对数据进行一些什么操作然后将 hEvent 栏位设定指向该结构 6在C 中产生一个I/O Completion Routines:储存一个指针指向用户自定义数据一个对象然后经由此指针调用一个 C 成员函数。由于 static 成员函数是类的一部分你还是可以调用 private 成员函数。 6.对文件进行overlapped I/O的缺点 1似乎 Windows NT 是以“I/O 请求”的大小来决定要不要将此请求先记录下来。所以对于数据量小的操作overlapped I/O的效率反而更低。 2解决办法以少量的线程负责所有的硬盘 I/O然后把这些线程的I/O 请求保持在一个队列之中。这种效率比较高。 3有两种情况overlapped I/O 总是同步执行甚至即使 FILE_FLAG_NO_BUFFERING 已经指定。第一种情况是你进行一个写入操作而造成文件的扩展。第二种情况是你读写一个压缩文件。 7.I/O Completion Ports 1APCs的缺点最大的问题就是有好几个 I/O APIs 并不支持 APCs如listen() 和 WaitCommEvent() 便是两个例子。APCs 的另一个问题是只有发出“overlapped 请求”的那个线程才能够提供 callback 函数然而在一个“scalable”译注系统中最好任何线程都能够服务 events。 2产生一个I/O Completion Port HANDLE CreateIoCompletionPort(HANDLE FileHandle, //文件或设备的handle若为INVALID_HANDLE_VALUE,则产生一个没有和任何handle关联的port。HANDLE ExistingCompletionPort, //若此栏位被指定则FileHandle被加到此port上。指定Null产生一个新的port。DWORD CompletionKey, //用户自定义的一个数值将被交给提供服务的线程。此值和FileHanlde有关联。DWORD NumberOfConcurrentThreads//与此I/O completion port 有关联的线程个数。); 3与一个文件handle产生关联 再次使用CreateIoCompletionPort接口。 4在一个I/O Completion Port上等待 BOOL GetQueuedCompletionStatus(HANDLE CompletionPort, //将在其上等待completion port。LPDWORD lpNumberOfBytesTransferred, //指向DWORD,收到“被传输的数据字节数”。LPDWORD lpCompletionKey, //指向DWORD,该DWORD将收到由CreateIoCompletionPort定义的key。LPOVERLAPPED *lpOverlapped, //overlapped结构指针的地址。DWORD dwMilliseconds //等待的最长时间时间终了lpOverlapped被设为NULL函数传回FALSE。); 在completion port上等待的线程是以先进后出的次序提供服务。 5避免Completion Packets 设定一个 OVERLAPPED 结构内含一个合法的手动重置manual-resetevent 对象放在 hEvent 栏位。然后把该 handle 的最低位设为 1。 overlap.hEvent CreateEvent(NULL, TRUE, FALSE, NULL); overlap.hEvent (HANDLE)((DWORD)overlap.hEvent | 0x1); WriteFile(hFile, buffer, 128, dwBytesWritten, overlap); 8.对Sockets使用Overlapped I/O 分析ECHO例子多实践socket IOCP。转载于:https://www.cnblogs.com/programmer-wfq/p/4646151.html