1. I/O设备
Windows支持的常见I/O设备包括有文件、目录、逻辑磁盘驱动器、物理磁盘驱动器、串口、并口、邮槽、管道、套接字、控制台。但对Windows系统层面来说,不太关心具体设备是为哪一种,将设备都抽象成是“文件”,对设备的操作即是对文件进行操作。常用的打开设备的API函数有:CreateFile()、CreateNamedPipe()(命令管道)、CreatePipe()(匿名管道)、Socket()(套接字)等。对设备数据进行读写的API函数是:ReadFile()和WriteFile()。
2.同步I/O
同步I/O是指我们调用一个函数来告知系统要对某个设备进行读取或写入数据,这个函数会一直等待I/O完成才会返回,在等待期间,调用函数的线程是处于阻塞状态的。为什么会阻塞呢? 是因为硬件特性导致速度不匹配的原因,速度较快的需等待速度相对慢的操作完成,拿到操作结果后才能往下继续执行。 假如打开设备(CreateFile)时是以同步方式打开,那么上面提到的ReadFile()和WriteFile()都是以同步方式进行I/O请求,如果想以异步方式调用,则在CreateFile打开设备时需设置异步FILE_FLAG_OVERLAPPED的参数标记。有个常见的例子,我们在使用有界面的窗口程序时,在用鼠标点击或键盘输入时,所产生的鼠标、键盘消息都会由操作系统添加到该窗口程序的消息队列中,由该窗口程序的界面线程来消费、处理。假设在鼠标点击或键盘输入时,窗口线程正在等待ReadFile()或WriteFile()返回而被阻塞,那么鼠标、键盘消息将得不到处理,就是我们所常见的程序窗口停止响应或未响应现象。
3.异步I/O
异步I/O与同步I/O是相对的,是指我们调用一个函数来告知系统要对某个设备进行读取或写入数据,但这个函数不会等待I./O完成,而是立即返回, 由操作系统在它自己的线程中完成具体的I/O操作,当操作系统 I/O操作完成后会有通知。上面有提到,用CreateFile打开设备时,指定FILE_FLAG_OVERLAPPED的参数标记就能异步方式打开,这样后面进行的I/O请求将会添加到设备驱动程序的队列中,由驱动程序完成实际的I/O操作,线程可以继续执行其它任务,不必挂起。
4.取消队列中I/O请求
有时我们可以需要在设备驱动程序对一个已经添加到队列的I/O请求者处理之前将其取消,取消的方式有如下几种:
1)调用CancelIo(HANDLE hFile);
2) 关闭设备句柄;
3)当线程终止时,操作系统会自动取消该线程所发出的所有I/O请求;
4)如果需要将发往给定文件句柄的一个指定的I/O请求取消,可使用 CancleIoEx(HANDLE hFile , LPOVERLAPPED pOverlappad);
5.接收I/O请求的通知
接收I/O请求通知的以下几种方法:
1)触发设备内核对象:允许一个线程发出I.O请求,另一个线程对结果进行处理;
2)触发事件内核对象: 允许向一个设备同时发出多个I/O请求, 允许 一个线程发出I/O请求,另一个线程对结果进行处理;
3)使用可提醒I/O: 允许向一个设备同时发出多个I/O请求, 发出I/O请求的线程必须对结果进行处理;
4)使用I/O完成端口: 允许向一个设备同时发出多个I/O请求, 允许 一个线程发出I/O请求,另一个线程对结果进行处理;这种伸缩性与灵活性最佳。
几种方法具体介绍与区别后续再进行了解。