windows 异步 IO
2014-12-04 15:16
141 查看
同步 IO:线程存在 IO 操作的时候,他会等待IO 操作完成之后才会继续执行后续操作,此时线程会被挂起,知道 IO 完成,线程才可以重新调度。
异步 IO:IO 的操作在后台进行,并不阻塞线程的继续运行,IO 的操作和线程运行同时进行。
同步 IO 由于线程的挂起,运行 发生大量的上下文切换,导致程序的性能降低。
如何选择同步还是异步呢?
主要有这么几个指标供参考
1. 并发数量
2. 接收字节数
3. 处理请求所需CPU时间
并发数
并发低的时候同步IO与异步IO差别不大
并发高时差别会比较明显,这要表现在
1. 开启线程数:如并发1000时,同步IO要开启1000个线程,1000个线程要占用很多内存,这是其一,其二1000个线程间切换的时间也是很可观的;异 步IO则可避免这个问题
接收字节数
接收字节越少被阻塞的概率越低,同步IO与异步IO的差别就越小
接收字节越多被阻塞的概率就越大,异步IO的优势越明显,能够同时服务更多的客户端请求
处理请求所需CPU时间
同步阻塞IO
服务端在调用read()时,如果网卡缓冲区中没有数据则程序停止向下执行,直到网卡缓冲区中有数据。
同步的非阻塞IO是这样的
服务端调用read()后,网卡缓冲区中如果没有数据可读就返回 ,服务器采用循环的方式再去读取
可以看出CPU大部分被浪费了
异步非阻塞IO
服务端调用read()方法,若网卡缓冲区中无数据则返回,程序继续向下执行。当缓冲区中有数据时,系统会通知应用程序。
windows 中异步 IO,其中一种方法就是 CreateFile 创建设备是设定 FILE_FLAG_OVERLAPPED 风格。
使用 ReadFile 读文件,和 WriteFile 写文件的时候都要 使用 OVERLAPPED 结构体。
OVERLAPPED 结构中有些成员都需要我们初始化。
offset 和 offsetHigh 指定我们从哪里开始 IO 操作。
hEvent 事件句柄,初始化为 无信号,IO 操作完成之后 系统会设置为有信号。如果我们调用 GetOverlappedResult 函数之后,hEvent 会被设置为无信号。
异步 IO:IO 的操作在后台进行,并不阻塞线程的继续运行,IO 的操作和线程运行同时进行。
同步 IO 由于线程的挂起,运行 发生大量的上下文切换,导致程序的性能降低。
如何选择同步还是异步呢?
主要有这么几个指标供参考
1. 并发数量
2. 接收字节数
3. 处理请求所需CPU时间
并发数
并发低的时候同步IO与异步IO差别不大
并发高时差别会比较明显,这要表现在
1. 开启线程数:如并发1000时,同步IO要开启1000个线程,1000个线程要占用很多内存,这是其一,其二1000个线程间切换的时间也是很可观的;异 步IO则可避免这个问题
接收字节数
接收字节越少被阻塞的概率越低,同步IO与异步IO的差别就越小
接收字节越多被阻塞的概率就越大,异步IO的优势越明显,能够同时服务更多的客户端请求
处理请求所需CPU时间
同步阻塞IO
服务端在调用read()时,如果网卡缓冲区中没有数据则程序停止向下执行,直到网卡缓冲区中有数据。
同步的非阻塞IO是这样的
服务端调用read()后,网卡缓冲区中如果没有数据可读就返回 ,服务器采用循环的方式再去读取
可以看出CPU大部分被浪费了
异步非阻塞IO
服务端调用read()方法,若网卡缓冲区中无数据则返回,程序继续向下执行。当缓冲区中有数据时,系统会通知应用程序。
windows 中异步 IO,其中一种方法就是 CreateFile 创建设备是设定 FILE_FLAG_OVERLAPPED 风格。
使用 ReadFile 读文件,和 WriteFile 写文件的时候都要 使用 OVERLAPPED 结构体。
OVERLAPPED 结构中有些成员都需要我们初始化。
ypedef struct _OVERLAPPED { ULONG_PTR Internal; ULONG_PTR InternalHigh; union { struct { DWORD Offset; DWORD OffsetHigh; }; PVOID Pointer; }; HANDLE hEvent; } OVERLAPPED, *LPOVERLAPPED;
offset 和 offsetHigh 指定我们从哪里开始 IO 操作。
hEvent 事件句柄,初始化为 无信号,IO 操作完成之后 系统会设置为有信号。如果我们调用 GetOverlappedResult 函数之后,hEvent 会被设置为无信号。
HANDLE hread = CreateFile(TEXT("D:\\readme.txt"), GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if(hread == INVALID_HANDLE_VALUE) { printf("CreateFile failed %lu\n", GetLastError()); return 1; } HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); OVERLAPPED oap; oap.hEvent = hEvent; oap.Offset = 0; oap.OffsetHigh = 0; DWORD _bytes = 0; while(1) { UINT8 buffer[MAX_PATH + 1] = {0}; if(!ReadFile(hread, buffer, MAX_PATH , NULL, &oap)) { if(GetLastError() == ERROR_IO_PENDING) { if(!GetOverlappedResult(hread, &oap, &_bytes, TRUE)) { printf("failed %lu\n", GetLastError()); return ; } if(_bytes == 0) return ; oap.Offset += _bytes; } else { printf("failed %lu\n", GetLastError()); } } }
相关文章推荐
- WSAAsyncSelect和windows客户端异步IO模型
- WINDOWS下异步IO
- Windows Via C/C++ 读书笔记 7 异步IO, 完成端口模式
- windows 核心编程之 10 同步设备IO与异步设备IO
- Windows IO模型-WSAAsynSelect模型(异步阻塞模型)
- Windows学习(005)--异步IO
- windows io 异步读写
- 网络编程(52)—— Windows下使用WSAEventSelect实现异步通知IO
- windowsViaC/C++设备IO之异步设备IO请求
- 在 windows IOCP 中,如何等待异步 IO 操作完成(包括被取消)[转]
- Windows异步IO
- 《Windows via C/C++》学习笔记 —— 设备I/O之“异步设备I/O请求”
- 使用Win32API实现Windows下异步串口通讯(上)
- Windows Presentation Foundatio目录
- 转载:异步IO、APC、IO完成端口、线程池与高性能服务器之一 异步IO
- 使用Win32API实现Windows下异步串口通讯(上)
- 出现在 WindowsNT、 Windows 2000, 和 WindowsXP, 同步异步磁盘 I/O
- 同步文件IO和异步文件IO
- Windows服务器端编程-第二章 设备IO与线程间通信-2-异步设备I/O操作基础
- 异步文件IO的应用