Win32 multi-threaded program design learning notes (Chapter 6)

zhaozj2021-02-08  199

carry on. . .

The above program fragment is waiting for the WaitFormultipleObjects function, there will be two questions:

First, you can only wait for less than 64 objects, which is the limitations that the waitformultipleObjects function itself.

Second, you have to calculate how to handle it according to "which Handle is excited". The structure of this program is not very clear, it is not convenient to maintain

Then, the book is here to provide a way of asynchronous process call (APCs) to solve these problems.

The core view of the APCS is to provide a function that automatically calls this function when the Overlapped I / O operation is complete.

Note: Use the APCS, readfileex (), Writefileex ()

example:

// Custom function, call when Overlapped I / O operation is completed

Void WinApi myfunc (dword dwerrorcode, // completion code

DWORD dwnumberofbytestransfered, // Number of bytes passed

LPOVERLAPPED LPOVERLAPPED / / Pointers to the Overlapped structure

)

{

// This uses a technique because uses APCS technology; then Overlapped structure

The // Event field is not used, you can use it to pass some parameters.

// Use it here to pass the serial number to indicate who has completed Overlapped I / O

INT NINDEX = (int) (lpoverlapped-> hent);

// Do some operations for NINDEX

Switch (Nindex)

{

Case 1: // Do some operations. . . Break;

Case 2: // Do some operations. . . Break;

... ..

}

// If all Overlapped I / O is processed, the global event is excited so that the main program ends

IF ( ncompletioncount == max_Requests)

SetEvent (ghevent);

}

int main ()

{

// Construct the global EVENT

Ghevent = CreateEvent (NULL, TRUE, FALSE, NULL);

// 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

WaitforsingleObjectEx (Ghevent, Infinite, True);

CloseHandle (GHFILE);

Return EXIT_SUCCESS;

}

INT QueueRequest (int NINDEX, DWORD DWLOCATION, DWORD DWAMOUNT)

{

// Record the serial number of Overlapped

Goverlapped [nindex] .hevent = (handle) Nindex;

// Record the file start point

Goverlapped [nindex] .offset = dwlocation;

// Automatically call myfun when the reading file is completed

Readfileex (GHFILE, GBuffers [Nindex], Dwamount, & Goverlapped [NINDEX], MyFunc);

The above three program fragments are specific to Overlapped I / O; dealing with general I / O operations should be, if you need higher efficiency, then you need the I / O Completion ports mentioned in the book. .

I / O Completion Ports may be the best way (see if you will feel this in P172-P173?);

But I / O Completion Ports seems to be difficult to understand, I tried to write an experience from the perspective of understanding my understanding (maybe it);

description:

Watch I / O Completion Ports as a container, then place several threads in this container (the book is preferably CPU number * 2 2), which will activate the service I / O request anytime, anywhere.

Why will I / O Completion Ports will be effective? I think so: First, the thread kept in the container can assume the task of the service I / O request at any time. The main feature is that the two threads can serve the same I / O request at different times;

Second: The scheduling of these threads is arranged by the system selection. The system is always going to schedule the most appropriate thing in it think the most appropriate timing. On the book, I also said some other work work, I will not be described in one.

Let's take a look at the use of I / O Completion Ports. This is our most concerned:

In P179, there is an operational Overview: Fighting it, I will explain the example of I / O Completion Ports on the book.

// Note: Be sure to make a book, clear the meaning of each parameter of the Win32 function used below, this is important

// ------ produce an I / O Completion Port 1

/ / Construct an I / O Completion Port

GHCompletionPort = CreateiocompletionPort

INVALID_HANDLE_VALUE,

NULL, // Do not use any port

0, // This parameter is used to pass the parameters between the thread, at this time

0 // Use the default thread number

);

// ------ Let it associate it with a file handle 2

// Associate Socket to 1 generated I / O Completion Port, then happened in this Socket

// Any I / O operation on //, thus processing in this I / O Completion Port

CreateiocompletionPort ((Handle) Newsocket, // Note, here is Socket; Reason See P184

GHCompletionport, // Specify I / O Completion Port

(DWORD) PKEY, / / ​​A pointer pointing to custom structure

0 // Use the default thread number

);

/ * pkey, used to record an operation that occurs on NewSocket, pointing to a custom structure

This structure saves data from the client and writes back to the customer's data * /

// ------ produce a pile of threads 3

CREATEWORKERTHREADS ();

// ------ below is 4, 5 steps

// The following code is in the thread function threadfunc

For (;;)

{

// ------ Let each thread wait on Completion Port 4

// The following function is equivalent to WaitforsingleObject; [Remind: This kind of waiting is not busy waiting]

// When a thread read operation is complete, this function returns BRESULT = GetQueuedCompletionStatus

GHCompletionPort, / / ​​Specify which port waiting for

& DWNumRead,

& (DWORD) PCNTX, // A pointer receives the key defined by Createiocompletionport

& lpoverlapped,

Infinite

);

/ * Description: PCNTX is the parameter pKEY in CreateiocompletionPort (); the read data is specified.

PKEY-> Inbuffer, take a closer look at the program code and P183's narrative, you will find it in I / O Completion Ports

The thread in the middle is to discriminate different clients through PKEY.

IF (BRESULT == After reading)

{/ Saved the read data to PCNTX-> Outbuffer

// Note: PCNTX-> NoutBufindex records the location of the current client read

Char * PCH = & PCNTX-> Outbuffer [PCNTX-> NoutBufindex ];

* PCH = PCNTX-> Inbuffer [0];

* PCH = '/ 0';

IF (PCNTX-> Inbuffer [0] == '/ n')

{// If you finish reading, write the information received back to the client.

// ------ Started some Overlapped I / O requests to the file Handle 5

Writefile

(Handle) (PCNTX-> SOCK),

PCNTX-> Outbuffer,

PCNTX-> Noutbufindex,

& pcntx-> dwwritten,

& PCNTX-> Ovout

);

PCNTX-> noutbufindex = 0;

}

// No finished reading

// ------ Started some Overlapped I / O requests to the file Handle 5

/ * Below this section I took the IssueRead (PCNTX) on the book, replacing it is the implementation of the IssueRead (PCNTX) function * /

// Read operation, trigger the operation of I / O Completion Port

BRESULT = ReadFile

(Handle) PCNTX-> SOCK, // Take the client's Socket

PCNTX-> Inbuffer, // Write the characters read from the client to Inbuffer

1, // Read a character each time

& numread,

& pcntx-> ovin // 嘿! This guy is not used here.

);

}

The above program fragment does not list the program code for "avoiding the completion packets".

When the write operation is complete, I / O Completion Port will receive a packets to explain whether the write operation is successful; if the result of the write operation (success or failure) is not very important, then we must not want to write every time Receive such a packets after the operation, I want to shield it, you can go down:

Overlapped overlap;

/ / Treated this below HEVENT

Overlap.hevent = creteEvent (...);

Overlap.hevent = (Handle) ((DWORD) OVERLAP.HEVENT | 0X1);

// So "Write" After using this processed Overlap, I / O Completion Port will not send packetswritefile (.... & Overlap);

Limited to my expression ability, some places can only have a hard description; this note is to help me to take the key to the next time, it may not use it for you, but why do I want? Write out? Because writing notes (I don't know how this can be noted), I can help me better understand the content of the book, this is my deep understanding. Looking back and looked at the book and found that these technical descriptions were very clear. The use of words is also very accurate, and a few words direct technology. So I suggest that everyone will repeat the book, you will suddenly open J (um! I just opened this).

Next note, I am going to write a better, I hope I don't know, let everyone understand! ! !

Note: The above text is purely to strengthen memory, content or unknown, or even mistakes, please forgive me, hurry !!!

转载请注明原文地址:https://www.9cbs.com/read-3146.html

New Post(0)