Windows asynchronous io (asynchronous Io) (1)

Source: Internet
Author: User

Question: I am studying windows SDK programming recently. I plan to share my learning summary and experiences with you, for more information, see <windows via C/C ++ 5th> and <programming Windows>. I try to use English terms to express technical concepts so that you can find other materials. The first article starts with asynchronous Io, represented by file IO.

 

Asynchronous Io is an essential feature of modern operating systems. It makes valuable CPU computing resources not wasted waiting for slow Io. Its behavior is intuitive. after sending an IO request, the user thread does not need to wait until the IO is complete, but directly returns to continue executing other tasks. After the device driver completes the I/O request, it notifies the user that the thread data transmission is complete and can perform related operations. Windows asynchronous Io consists of two steps: 1) Send an IO request to the device driver; 2) notify the user that the data transmission has been completed after completing the IO request, completion notification ). This article mainly introduces step 1: sending IO requests.

 

The asynchronous file IO operations in Windows SDK mainly involve the following basic functions: createfile, readfile, and writefile.

1,Handle createfile (<br/> pctstr pszname, <br/> DWORD dwdesiredaccess, <br/> DWORD dw1_mode, <br/> psecurity_attributes PSA, <br/> DWORD dwcreationdisposition, <br/> DWORD dwflagsandattributes, <br/> handle hfiletemplate );

This function is used to open a device, including files. When sending an asynchronous Io request, you must specify the file_flag_overlapped flag in the dwflagsandattributes parameter to inform the system that you want to access the device asynchronously.

2,Bool readfile (<br/> handle hfile, <br/> pvoid pvbuffer, <br/> DWORD nnumbytestoread, <br/> pdword pdwnumbytes, <br/> overlapped * poverlapped ); </P> <p> bool writefile (<br/> handle hfile, <br/> const void * pvbuffer, <br/> DWORD nnumbytestowrite, <br/> pdword pdwnumbytes, <br/> overlapped * poverlapped );

You will use these two functions for Synchronous Io, for example:

# Include <windows. h> <br/> # include <stdio. h> <br/> int main () <br/>{< br/> handlehfile = NULL; <br/> bytebuff [1024]; <br/> dworddwread = 0; </P> <p> hfile = createfile (text ("data.txt"), generic_read, file_1__read, <br/> 0, open_existing, 0, null ); </P> <p> readfile (hfile, buff, 1024, & dwread, null); </P> <p> printf ("% s", buff ); </P> <p> return exit_success; <br/>}

Here, the poverlapped parameter is set to null. During asynchronous Io, you must use this parameter to specify an overlapped structure for this Io request. The data members are as follows:

Typedef struct _ overlapped {<br/> DWORD internal; // [out] Error Code <br/> DWORD internalhigh; // [out] number of bytes transferred <br/> DWORD offset; // [in] low 32-bit file offset <br/> DWORD offsethigh; // [in] High 32-bit file offset <br/> handle hevent; // [in] event handle or data <br/>} overlapped, * lpoverlapped;

Where:

As an output parameter, internal returns the error code of this Io request.

Internalhigh is used as the output parameter and returns the number of bytes read and write in this Io request.

Offset and offsethigh are used as input parameters to specify the start offset of the IO request. This is different from Synchronous IO: for each file core object, all IO requests are executed in sequence and cannot overlap (the origin of overlapped names ), the START offset of each Io is specified by the file pointer of the file core object. However, in asynchronous Io, multiple IO requests may overlap. In this way, the file pointer in the file core object is meaningless, therefore, each Io request must specify the start offset separately in the overlapped structure.

Hevent is used as the input parameter to complete the notification ). It will be detailed later.

As can be seen from the above functions, the information provided by overlapped covers almost all aspects of an IO request. In fact, each Io request corresponds to an overlapped, which is the channel through which the user communicates with the device driver. Therefore, the overlapped structure must be valid until the entire Io request is completed.

After you use readfile/writefile to send an IO request to the device driver, you must carefully check the function return values:

1) if a non-zero value is returned, the IO request is completed immediately and returned. At this time, the IO request does not enter the Request queue. This is completely possible for asynchronous IO requests, because the system may cache the content requested by the user at this time, so the request can be completed immediately.

2) if false is returned, getlasterror must be called immediately for further judgment. If getlasterror returns error_io_pending, this Io request is successfully added to the Request queue. If other values are returned, this Io request cannot be added to the Request queue. The following are common return values for failed requests:

Error_invalid_user_buffer/error_not_enough_memory indicates that the queue is full and cannot be added to new requests. Reference code:

# Include <windows. h> <br/> # include <stdio. h> <br/> int main () <br/>{< br/> handlehfile = NULL; <br/> bytebuff [1024]; <br/> overlappedol = {0}; <br/> boolbret = false; <br/> dworddwcode = 0; </P> <p> hfile = createfile (text ("data.txt"), generic_read, file_1__read, <br/> 0, open_existing, file_flag_overlapped, null ); </P> <p> ol. offset = 16; // read data from file starting at byte 16 <br/> Bret = readfile (hfile, buff, 1024, null, & ol ); </P> <p> If (BRET) // Io request is completed immediately <br/>{< br/>}< br/> else if (dwcode = getlasterror () = error_io_pending) // Io request is queued successfully <br/>{< br/>}< br/> else <br/>{< br/> // error handling here <br/>} </P> <p> return exit_success; <br/>}

As we have mentioned earlier, the internal Member in the overlapped structure is returned as the error code of this Io request. Therefore, we can check this variable to determine the status of the current IO request. After sending an IO request, if the request is successfully added to the queue, the internal variable in the overlapped structure will be set to status_pending. In fact, Windows provides us with a macro:

# Define hasoverlappediocompleted (poverlapped)/<br/> (poverlapped)-> internal! = Status_pending)

Overlapped provides almost all the information we need, which fully demonstrates that it is a channel for users to communicate with device drivers.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.