When we read and write to the file, the thread should be blocked, that is, the thread is waiting for the end of the read and write operation, which is called
synchronous I/O。 Windows provides us with an efficient mechanism at the system level-
Asynchronous IO。
Asynchronous IO provides a function: When you read a file, the Read function returns immediately, and the read task is forwarded to the system's underlying automatic processing so that the read operation of the file does not block the thread. When the IO operation is complete, the system issues a completion notification.
Three notifications of completion are introduced:
1. Direct wait handle (file wait object)
2. Wait for the hevent handle in overlapped (wait for event object)
3. Asynchronous invocation (APC invocation)
Main functions: CreateFile (); ReadFile (); WriteFile ();
Data member: OVERLAPPED structure.
If a handle is opened in asynchronous Io, the handle has two features :
1. The file becomes a waiting object (that is, an excited state and a non-excited state)
2. File pointer invalidation (needs to be read or written by Offect in the overlapped struct, rather than functions such as SetFilePointer (). )
code example: (VS2015 console)
Prepare: Create 123.exe in the Debug directory and save the data
1. Direct wait handle
#include "stdafx.h" #include <windows.h>typedef struct _myoverlapped{OVERLAPPED ol; HANDLE hfile; Pbyte PBuf; int NIndex;} Myoverlapped,*pmyoverlapped;dword WINAPI ThreadProc (lpvoid lParam) {pmyoverlapped pol = (pmyoverlapped) LParam; WaitForSingleObject (Pol->hfile, INFINITE); for (int i=0;i<10;i++) {printf ("%d:%d \ n", Pol->nindex,pol->pbuf[i]); } printf ("Finished reading!") \ n "); return 0;} int main () {//1. Asynchronous IO tag//With this tag the file becomes a waiting kernel object//After the read write function becomes non-blocking HANDLE hfile = CreateFile (L "123.tx T ", Generic_read, File_share_read, NULL, open_existing, file_attribute_normal| File_flag_overlapped, NULL); 2. File Read pmyoverlapped pol = new myoverlapped{}; Pol->ol. offset = 0x0;//start at offset 0x100 This position read//Pol->hevent = = NULL; After the system reads, it will turn my hfile into a signal state pol->hfile = hfile; Pol->pbuf = new byte[0x1000]{}; Pol->nindex = 1; ReadFile (hfile, Pol->pbuf, 0x1000, null,//the actual number of reads, by Overlapped structure Designation (lpoverlapped) POL); HANDLE hthread = CreateThread (null, NULL, THREADPROC, POL, NULL, NULL); pmyoverlapped pol2 = new myoverlapped{}; Pol2->ol. offset = 0x0;//start at offset 0x100 This position read//Pol->hevent = = NULL; After the system reads, it will turn my hfile into a signal state pol2->hfile = hfile; Pol2->pbuf = new byte[0x1000]{}; Pol2->nindex = 2; ReadFile (hfile, Pol2->pbuf, 0x1000, null,//actual number of reads, specified by the OVERLAPPED structure (lpoverlapped) pol2); HANDLE hThread2 = CreateThread (null, NULL, THREADPROC, pol2, NULL, NULL); // ...... Do other things WaitForSingleObject (Hthread, INFINITE); WaitForSingleObject (HThread2, INFINITE); return 0;}
2. Wait for the event object
#include "stdafx.h" #include <windows.h>typedef struct _myoverlapped {OVERLAPPED ol; HANDLE hfile; Pbyte PBuf; int NIndex;} myoverlapped, *pmyoverlapped;dword WINAPI threadproc (lpvoid lParam) {pmyoverlapped pol = (pmyoverlapped) LParam; printf ("Start waiting ... \ n"); WaitForSingleObject (Pol->ol.hevent, INFINITE); for (int i = 0; i < i++) {printf ("%d:%02x \ n", Pol->nindex, Pol->pbuf[i]); } printf ("Finished reading!") \ n "); return 0;} int main () {//1. Asynchronous IO tag//With this tag the file becomes a waiting kernel object//After the read write function becomes non-blocking HANDLE hfile = CreateFile (L "). \\Debug\\123.exe ", Generic_read, File_share_read, NULL, open_existing, File_attribute_normal | File_flag_overlapped, NULL); 2. File Read pmyoverlapped pol = new myoverlapped{}; Pol->ol. Offset = 0x100;//starts at offset 0x100 This position reads pol->ol.hevent = CreateEvent (null,null,false,null); After the system reads, it turns my hfile into a signaled state Pol->hfile = hfile;//is ignored pol->pbuf = new byte[0x1000]{}; Pol->niNdex = 1; ReadFile (hfile, Pol->pbuf, 0x1000, null,//actual number of reads, specified by the OVERLAPPED structure (lpoverlapped) pol); HANDLE hthread = CreateThread (null, NULL, THREADPROC, POL, NULL, NULL); pmyoverlapped pol2 = new myoverlapped{}; Pol2->ol. Offset = 0x200;//starts at offset 0x100 This position reads pol2->ol.hevent = CreateEvent (null, NULL, FALSE, NULL); After the system reads, it turns my hfile into a signaled state Pol2->hfile = hfile;//is ignored pol2->pbuf = new byte[0x1000]{}; Pol2->nindex = 2; ReadFile (hfile, Pol2->pbuf, 0x1000, null,//actual number of reads, specified by the OVERLAPPED structure (lpoverlapped) pol2); HANDLE hThread2 = CreateThread (null, NULL, THREADPROC, pol2, NULL, NULL); // ...... Do other things WaitForSingleObject (Hthread, INFINITE); WaitForSingleObject (HThread2, INFINITE); return 0;}
3. Asynchronous invocation (APC invocation) provides a mechanism for asynchronous invocation: You can provide a callback function when reading a file or writing to a file, and the callback function is called when the read-write task is completed.
#include "stdafx.h" #include <windows.h>typedef struct _myoverlapped {OVERLAPPED ol; HANDLE hfile; Pbyte PBuf; int NIndex;} myoverlapped, *pmyoverlapped;//commits the thread processing of the task, other threads look at void CALLBACK fileiocompletionroutine (_in_ DWORD Dwerrorcode , _in_ DWORD dwnumberofbytestransfered, _inout_ lpoverlapped lpoverlapped) {pmyoverlapped pol = (Pmyov erlapped) lpoverlapped; for (int i = 0; i < i++) {printf ("%d:%02x \ n", Pol->nindex, Pol->pbuf[i]); } printf ("Finished reading!") \ n ");} int main () {//1. Asynchronous IO tag//With this tag the file becomes a waiting kernel object//After the read write function becomes non-blocking HANDLE hfile = CreateFile (L "). \\Debug\\123.exe ", Generic_read, File_share_read, NULL, open_existing, File_attribute_normal | File_flag_overlapped, NULL); 2. File Read pmyoverlapped pol = new myoverlapped{}; Pol->ol. offset = 0x100;//start reading from offset 0x100 This position//hevent is ignored hfile also ignored//pol->ol.hevent = CreateEvent (null, NULL, FALSE, NULL ); After the system reads, my hfile will bebecomes signaled state pol->hfile = hfile;//is ignored pol->pbuf = new byte[0x1000]{}; Pol->nindex = 1; ReadFileEx (hfile, Pol->pbuf, 0x1000, (lpoverlapped) pol, fileiocompletionroutine);//Direct Call after completion The callback function does not have to wait for the file handle/Event object pmyoverlapped pol2 = new myoverlapped{}; Pol2->ol. Offset = 0x200;//starts at offset 0x100 This position reads//pol2->ol.hevent = CreateEvent (null, NULL, FALSE, NULL); After the system reads, it turns my hfile into a signaled state//pol2->hfile = hfile;//is ignored pol2->pbuf = new byte[0x1000]{}; Pol2->nindex = 2; ReadFileEx (hfile, Pol2->pbuf, 0x1000, (lpoverlapped) pol2, fileiocompletionroutine); Fileiocompletionroutine has a system call//which thread executes the function//which thread read/write which thread executes//... Do other things//busy thinking about two more functions waiting for me.//CPU detects the current thread in the APC queue where there is a function to execute//go to execute the function, execute the return///only when the 2nd parameter is true to execute SleepEx (x, T RUE);//WaitForSingleObjectEx () return 0;}
Detailed windows asynchronous I/O