关于Winsock编程中IO重叠的概念
我在看《Windows网络与通信程序设计》(王艳平)这本书时,对重叠IO很不理解,突然就冒出这么一个概念,没一点头绪。就目前的理解做一个整理。
第一种理解:OVERLAPPED,顾名思义为重叠,乍一看会很奇怪,重叠?谁跟谁重叠?似乎在WIN32的Programming中没有这个概念呀?要讨论这个问题就要追溯到对设备I/O的访问中。
在WIN32中,用户不能象以前那样直接对硬件进行访问,使得这一层对开发者而言是个"黑盒",而提供了一组对应的API的接口.让开发者基于提供的接口进行开发,而把低层的访问交给了Driver或者内核.在WIN32中,设备的概念已经远远超过了Moniter,Printer等的范围,大概可以包括文件,目录,串口,并口,管道以及控制台等.很自然的,当我们要访问这个设备的时候,我们的第一步就是打开这个设备,其中WIN32 API提供的是CreateFile,具体的使用可以参考MSDN,其中包括的一些参数表明了是否这个设备已经存在(dwCreationDisposition),是否以独占的方式(dwShareMode)打开等等.这里大家可能已经产生了这个想法:呀,既然是跟设备打交道,那么设备的速度这么慢,而CPU的速度这么快,这两者应该怎么协调好呢?举个例子说,我要访问软盘上的资料,哪怕它是一秒后就读出来了,那其实对CPU也是一种很大的浪费呀.是的,的确会有这个问题,既然有问题,我们就要解决,而MicroSoft的解决方式就是这里我们的讨论题目:OverLapped这个字符到底是什么含义呢?其实它的意思就是当程序在等待设备操作的时候,可以继续往下做而不必阻塞到那个地方等待设备操作的返回,这就造成了程序运行和设备操作时间上的重叠.是的,是这样的,神奇吧,那么程序该怎么知道设备操作什么时候做完了返回了呢...
第二种理解:
在windows中有一个api叫readfile
bool readfile(
handle hfile, // handle to file
lpvoid lpbuffer, // data buffer
dword nnumberofbytestoread, // number of bytes to read
lpdword lpnumberofbytesread, // number of bytes read
lpoverlapped lpoverlapped // overlapped buffer
);
如果我们在createfile的时候没有使用file_flag_overlapped 标志,同时在调用readfile的时候把lpoverlapped lpoverlapped 这个参数设置的是null,那么readfile这个函数的调用一直要到读取完数据指定的数据后才会返回,如果没读取完,就会阻塞在这里。同样 ,writefile和readfile都是这样的。这样在读写大文件的时候,我们很多时间都浪费在等待readfile和writefile的返回上面。如果readfile和writefile是往管道里读写数据,那么有可能阻塞得更久,导致程序性能下降。为了解决这个问题,windows引进了重叠io的概念,同样是上面的readfile和writefile,如果在createfile的时候设置了file_flag_overlapped ,那么在调用readfile和writefile的时候就可以给他们最后一个参数传递一个overlapped结构。这样readfile或者 writefile的调用马上就会返回,这时候你可以去做你要做的事,系统会自动替你完成readfile或者writefile,在你调用了 readfile或者writefile后,你继续做你的事,系统同时也帮你完成readfile或writefile的操作,这就是所谓的重叠。使用重叠io还有一个好处,就是你可以同时发出几个readfile或者writefile的调用,然后用waitforsingleobject或者 waitformultipleobjects来等待操作系统的操作完成通知,在得到通知信号后,就可以用getoverlappedresult来查询 io调用的结果。
基本上就这样,。不知道你清楚了没有,,,
至于socket里的重叠io,和这个差不错,不同的是readfile writefile被wsarecv和wsasend所代替了。这其中牵涉到的东西很多,其实有关windows的异步io机制,是很高深的,所以开始我才推荐你去看《windows2000编程内幕》,也可以去看《inside windows2000》
当cpu执行你的代码时遇上一个i/o请求[诸如读写文件之类的],系统产生一个中断,让cpu去完成这个i/o请求,等到完成了以后,系统再次产生一个中断让原先的程序继续运行。也就说通过中断保持这两者间的同步。可以将终端理解为硬件化的信号量。
这就是所谓的同步概念,一个线程中只可能同时处理一个i/o请求
你要知道,一个i/o操作是非常耗时的,当你的代码挂起后等待i/o完成的这段时间内,你的这个线程浪费了n个指令周期。
如果同时要反复读写大文件,用同步的效率是很低的。
为了解决这个问题,当cpu执行你的代码时遇上一个i/o请求后,系统这是为你开一根内部线程去处理i/o请求,并且你的线程并不挂起,但你可能会觉得如果i/o还没完成,后续的代码就算他让我执行,我也执行不下去了嘛?
如果下面的代码和这个i/o操作有关的话,那么它就要等一等,等到这个i/o操作完成,通过在一个线程中调用waitformultiobject()和getoverlappedresult()就可以得到i/o完成的消息,然后再对其作相应的处理。
但如果后续的代码和这个i/o操作无关,你就可以以更快的速度之行下去了,而无需等待io请求的完成了
这也就是异步了
你想当你有这样一个请求,就是
readfile(...) -1
writefile(...) -2
readfile(...) -3
你在程序中如果使用同步的话,那只有当你完成1以后2才会继续执行,2执行完以后3才会继续执行。这就是同步。
当如果使用异步的话,当系统遇到1时,ok,开一线程给它去完成该io请求,然后系统继续运行2,3,分别开两线程。
1-2-3如果是比较耗时的操作,尤其是运用在网络上,那么1-2-3这三个io请求是并行的,也就是重叠的。
重叠i/o就是能够同时以多个线程处理多个i/o,其实你自己开多个线程也可以处理多个i/o,当然系统内部优化以后肯定性能要比你的强,呵呵。
我只是简单的说了一下重叠[overlapped]没从代码的角度给你分析。希望你能对重叠io有所理解。看看windows网络编程,上面不是有模型嘛
最后提一下重叠模型的缺点,他为每一个io请求都开了一根线程,当同时有1000个请求发生,那么系统处理线程上下文[context]切换也是非常耗时的,所以这也就引发了完成端口模型iocp,用线程池来解决这个问题,我就不多说了。
关于Winsock编程中IO重叠的概念的更多相关文章
- 【Java并发编程】6、volatile关键字解析&内存模型&并发编程中三概念
volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以 ...
- volatile关键字解析&内存模型&并发编程中三概念
原文链接: http://www.cnblogs.com/dolphin0520/p/3920373.html volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java5之前,它是一个 ...
- Python之☞网络编程中一些概念问题(未完)
:::一些名词的解释::: 网络: 网络是辅助双方能够连接在一起的工具,使用网络的目的,为了联通多方然后进行通讯,能够让软件在不同的电脑上运行,相互传输数据. 网络协议: 约定俗成的,没有理由. TC ...
- winsock编程IOCP模型实现代码
winsock编程IOCP模型实现代码 话不多说,上代码.借鉴<windows核心编程>部分源码和CSDN小猪部分代码. stdafx.h依赖头文件: #include <iostr ...
- 一文读懂高性能网络编程中的I/O模型
1.前言 随着互联网的发展,面对海量用户高并发业务,传统的阻塞式的服务端架构模式已经无能为力.本文(和下篇<高性能网络编程(六):一文读懂高性能网络编程中的线程模型>)旨在为大家提供有用的 ...
- Winsock编程基础介绍 .
相信很多人都对网络编程感兴趣,下面我们就来介绍,在网络编程中应用最广泛的编程接口Winsock API. 使用Winsock API的编程,应该了解一些TCP/IP的基础知识.虽然你可以直接使用Win ...
- winsock编程WSAEventSelect模型
winsock编程WSAEventSelect模型 WSAEventSelect模型和WSAAsyncSelec模型类似,都是用调用WSAXXXXXSelec函数将socket和事件关联并注册到系统, ...
- winsock编程select模型
winsock编程select模型 网络服务端连接数量过多时,为每一个连接申请一个线程会让机器性能急剧下降(大多说是因为线程在用户态和内核态之间切换会占用大量的CPU时间片).为了解决多线程带来的性能 ...
- java中io对文件操作的简单介绍
11.3 I/O类使用 由于在IO操作中,需要使用的数据源有很多,作为一个IO技术的初学者,从读写文件开始学习IO技术是一个比较好的选择.因为文件是一种常见的数据源,而且读写文件也是程序员进行IO编程 ...
随机推荐
- 【转】Linux下Android ADB驱动安装详解
原文网址:http://blog.csdn.net/zhenwenxian/article/details/5901350 Linux下Android ADB驱动安装详解 概述 最近由于内置的合作商比 ...
- shell数组(产生不同的随机数)
#!/bin/bash # declare -a ARRAY read -p "Please input num[1-39]:" EMENUM #对比新生成的随机数是否重复 fun ...
- hdu 5641 King's Phone(暴力模拟题)
Problem Description In a military parade, the King sees lots of new things, including an Andriod Pho ...
- Unity5 游戏小实例(方块男去打架吧)
开发了将近半个月,最近进入一家游戏公司下班时间都是9点钟. 回到家里哪里还有时间去搞其他小东西, =.=这个小实例一直拖得太长了,先上一个版本.以后在慢慢修改. 项目下载地址: http://yu ...
- qt model/view 架构自定义模型之QFileSystemModel
# -*- coding: utf-8 -*- # python:2.x #QFileSystemModel """ Qt 内置了两种模型:QStandardItemM ...
- PHP设计模式笔记二:面向对象 -- Rango韩老师 http://www.imooc.com/learn/236
SPL标准库的使用 SPL是用于解决典型问题(standard problems)的一组接口与类的集合. 1.SPL提供了很多数据结构类,如SplStack.SqlQueue.SqlHeap.SplF ...
- Nexus 刷机
@echo offfastboot flash bootloader bootloader-hammerhead-hhz12k.imgfastboot flash radio radio-hammer ...
- mybatis于Date和DateTime现场插入
最近,该公司使用MyBatis3做数据持久层,有在该领域Date和DateTime种类,只有在插入数据时属性设置为一个实体Timestamp将相应mysql的DateTime类型.Date会相应mys ...
- DE2带的IP核ISP12362报错问题解决 Error:avalon_slave_1_irq: associatedAddressablePoint out of range
问题来源与对友晶提供的ISP1362 IP核的使用,由于Quartus II版本问题,它提供的IP基于7.0版本,而我用的版本为11.1,在SOPC Builder中重新加载IP,就出现了上述的错误报 ...
- 前端--关于javascript对象
在javascript中对象是一种基本的数据类型,在数据结构上是一种散列表,可以看作是属性的无序集合,除了原始值其他一切都是对象.它可以用来表示现实世界中或者我们大脑中抽象出来的客体,这和其他面向对象 ...