Win32 multi-threaded programming learning notes (Chapter 6)
We know that when the program calls I / O devices handles some things, it is not efficient to stop the completion of the main program. There are several solutions to this issue:
Method 1: Use another thread for I / O. However, from the previous learning, the relationship between coordination lines is a trouble, it takes careful design; so this program is feasible, but trouble.
Method 2: Use Overlapped I / O. As mentioned in the book: "Overlapped I / O is a technology of Win32, you can ask the operating system to transfer data for you, and notify you when the transfer is completed. This technology makes your program in the process of I / O It is still able to continue to handle the transaction. In fact, inside the operating system is threaded I / O to complete Overlapped I / O. You can get all the benefits of the thread, without having to pay any painful price. " what! This is a good way! ! !
The following is to talk about how to use Overlapped I / O:
Specify Overlapped mode when performing I / O operation
Using CREATEFILE (), specify its sixth parameter as file_flag_overlapped, is preparing to construct or open files using Overlapped; if you use overlapped, readfile (), WriteFile ()'s fifth parameter must provide a pointer, point to one Overlapped structure. Overlapped is used to record some related information that is currently being operated.
// Reference the example in the book below, to explain Overlapped:
// Function: 300 bytes from the 1500 location of the specified file
int main ()
{
BOOL RC;
Handle hfile;
DWORD NUMREAD;
Overlapped overlap;
Char BUF [512];
Char szpath = "x: // xxxx / xxxx";
/ / Check the system, determine if Overlapped is supported, (NT or more operating system support overlapped)
CheckosVersion ();
// Open the file in Overlapped
Hfile = CREATEFILE (Szpath,
Generic_read,
File_share_read | file_share_write,
NULL,
Open_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL
);
// Overlapped structure is initiated to 0
MEMSET (& overlap, 0, sizeof (overlap);
/ / The specified file location is 1500;
Overlap.offset = 1500;
Rc = readfile (HFile, BUF, 300, & Numread, & overlap);
// Because it is OVERLAPPED operation, readfile will return the read file request after the read queue is immediately returned (false).
// without waiting until the file reading is only returned (TRUE)
IF (rc)
{
// The file is really read, RC is true.
// or data is placed in cache, or the operating system thinks it can quickly get data quickly, RC is TRUE
}
Else
{
IF (getLastError () == Error_io_pending)
{// When the error is Error_IO_PENDING, it means that the operation of reading the file is still in progress
// Waiting until the file is read
WaitforsingleObject (HFILE, Infinite);
RC = GetoverlappedResult (Hfile, & Overlap, & NumRead, false); / / The function of the two statements is completed with the functionality of the following statement:
// GetoverlappedResult (Hfile, & Overlap, & Numread, true);
}
Else
{
//error
}
}
CloseHandle (HFILE);
Return EXIT_SUCCESS;
}
After reading the above program, there is a probably impression on Overlapped; then we continue to explore the powerful function of Overlapped I / O.
In actual work, there may be multiple operations while using the same file handle, then the above program is no longer applicable.
How to do? We can use Event provided in the Overlapped structure to solve the problems encountered above. Note that the EVENT object you use must be a manual type; otherwise, a competitive condition may occur. Reason before the book P159.
// Program fragment:
int main ()
{
INT I;
BOOL RC;
Char szpath = "x: // xxxx / xxxx";
// Open the file in Overlapped
GHFILE = CREATEFILE (SZPATH,
Generic_read,
File_share_read | file_share_write,
NULL,
Open_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL
);
For (i = 0; i { // Press the same file to the overlapped method simultaneously // Note how the queuerequest function is made QueueRequest (i, i * 16384, read_size); } // Waiting for all operations; // Include conditions: When an operation is completed, its corresponding EVENT object will be activated. WaitFormultipleObjects Max_Requests, Ghevents, True, Infinite ); // Tailing operation For (i = 0; i { DWORD DWNUMREAD; Rc = GetoverlappedResult GHFILE, & goverlapped [i], & DWNumRead, False ); CloseHandle (goverlapped [i] .hevent); } CloseHandle (GHFILE); Return EXIT_SUCCESS; } // After the read operation is completed, Goverlapped [Nindex] .hevent will system excited INT QueueRequest (int NINDEX, DWORD DWLOCATION, DWORD DWAMOUNT) { / / Construct a manual type EVENT object Ghevents [Nindex] = CreateEvent (NULL, TRUE, FALSE, NULL); // Place this EVENT object into the Overlapped structure Goverlapped [nindex] .hevent = Ghevents [NINDEX]; Goverlapped [nindex] .offset = dwlocation; For (i = 0; i { // File GHFILE unique Rc = readfile (GHFILE, GBuffers [Nindex], & DwnumRead, & Goverlapped [NINDEX]); // handle success IF (rc) Return True; Err = getLastError (); IF (Err == Error_io_ped) { // When the error is ERROR_IO_PENDING, it means that the operation of reading the file is still in progress. Return True; } // Handle some recoverable errors IF (err == error_INVALID_USER_BUFFER || Err == Error_not_enough_quota || Err == Error_not_enougon_memory { Sleep (50); Continue; // Retry } // If getlasterror () returned is not the error listed above, give up Break; } Return -1; } Hi! When everyone's resistance, it is definitely awkward, what is written here, and the Xuanke. Oh, no way, this thing is not good, only write two program fragments, strengthen memory, forgive, forgive me! ! !