Poedu_Windows_异步IO操作(1)

异步IO

使用CreateFile打开大文件或者其它设备的时候,如果是用的同步IO模式,就有可能会造成阻塞,因此也就有了异步IO模式

异步IO机制

在调用openFile的时候,就会向操作系统的设备发送请求,openFile会直接返回;
操作系统看到这个请求,会进行操作
当操作完成之后,会发给程序一个通知

做很多的操作的时候,都仅仅是发送个请求,直接返回,程序会做自己的事情,操作系统做实际操作,等待操作完成后,直接去拿,使得程序无须等待,在特定的一些情况下的使用

进程、线程与阻塞

进程

是当前运行程序的空间(主要做存储)

线程

是实际运行的单位(工作单位)

操作阻塞

指的是线程被停止、阻塞

进程是工厂,是一个空间,一块地盘,而线程是在里面的工人,工人可以有很多,也就是多线程

多线程

通过系统线程帮我们完成

异步操作——CreateFile

在之前的文章中,对CreateFile进行了浅析,参数dwFlagsAndAttributes的属性值中,有这么一个值:FILE_FLAG_OVERLAPPED,此时此文件或设备被打开或创建,用于异步 I/O

CreateFile的返回值(HANDLE)接下来的操作(Read和Write)都会以异步的方式进行

重要的一个结构体——OVERLAPPED结构体

原型
“`
typedef struct _OVERLAPPED {
ULONG_PTR Internal;
ULONG_PTR InternalHigh;
union {
struct {
DWORD Offset;
DWORD OffsetHigh;
};
PVOID Pointer;
};
HANDLE hEvent;
} OVERLAPPED, *LPOVERLAPPED;

>>ULONG_PTR Internal 
>>>保存错误码、当前操作是否完成
>
>>ULONG_PTR InternalHigh
>>>用来保存传输成功的字节数
>>>>
>
>>DWORD offset
>>DWORD offsetHigt
>>>两个DWORD组成一个64位数值
>>>
>>>以异步操作的方式打开设备时,设备对象并不会保存以前的位置,所以就必须告诉它从哪个位置开始操作
>>>>ReadFile与WriteFile中的参数中的实际读取/写入参数,在同步的时候是有用的,但是在异步的时候没用,因为程序是直接返回。所以需要用OVERLAPPED结构体中的InternalHigh来判断实际写入/读取的字节数
>
>>>天生带有文件分割的功能,因为可以设置从哪开始!
>>>
>>>同步的时候一般都设为nullptr
>
>>HANDLE hEvent
>>>事件内核对象,操作系统通知程序的一种方式
>



简单实例

#include < Windows.h>
#include < tchar.h>

int main()
{
HANDLE hFile = CreateFile(TEXT(“Test.txt”),
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_ALWAYS,
FILE_FLAG_OVERLAPPED,
NULL);

if (hFile == INVALID_HANDLE_VALUE)
    return -1;

OVERLAPPED overLapped = { 0 };//开始读取位置也设为0了,如果需要,还可以在下面程序中修改
overLapped.Offset = 100;    // 从100开始读

BYTE bBuffer[MAXBYTE] = { 0 };
BOOL bRet = ReadFile(hFile, 
        bBuffer, 
        MAXBYTE,
        NULL,
        &overLapped);//实际读取的字符设为NULL,因为它已经没啥用了
DWORD dwRet = GetLastError();

if (bRet && dwRet == ERROR_IO_PENDING)
{
    // 请求发送成功
    // 写自己的逻辑,
    //用途:一个用户请求来了,需要马上处理的,就可以在这边进行操作
    // ...
    WaitForSingleObject(hFile, INFINITE);   // 阻塞到请求完成
    // 演示用, 正式环境请不要使用此方法,会按条件阻塞,好处是可以在上面写自己的逻辑
}

CloseHandle(hFile);

return 0;

}
“`

WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds)

Windows API函数。当等待仍在挂起状态时,句柄被关闭,那么函数行为是未定义的。该句柄必须具有 SYNCHRONIZE 访问权限。

参数

hHandle

[in],对象句柄。可以指定一系列的对象,如Event、Job、Memory resource notification、Mutex、Process、Semaphore、Thread、Waitable timer等

dwMilliseconds

[in],定时时间间隔,单位为milliseconds(毫秒)。

如果指定一个非零值,函数处于等待状态直到hHandle标记的对象被触发,或者时间到了。

如果指定一个非零值,函数处于等待状态直到hHandle标记的对象被触发,或者时间到了。

如果指定一个非零值,函数处于等待状态直到hHandle标记的对象被触发,或者时间到了。

参数dwMilliseconds有两个具有特殊意义的值:0和INFINITE。若为0,则该函数立即返回;若为INFINITE,则线程一直被挂起,直到hHandle所指向的对象变为有信号状态时为止。

如有错误,烦请指正…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值