The thread pool solves the problem that multithreading is difficult to manage. Windows mainly provides the following methods for implementation:
- Asynchronous function call: Applicable in Server Client Mode
- Scheduled callback function: prevents multiple timers from occupying the CPU processing time of the main thread.
- Kernel Object notification Status callback: multiple threads are waiting for the same kernel object to apply
- Call a function upon completion of an asynchronous Io request: Applicable to asynchronous Io operations
1) Implement Asynchronous function calls
Scenario where a server creates a thread to process client requests
Mainthread-> wait for client request-> createthread handle request-> waitfor client request
Usage:
Called when the server receives a client request
Bool winapi queueuserworkitem (
_ In lpthread_start_routine function,
_ In_opt pvoid context,
_ In ulong flags
);
Note: The Execution Process is unordered.
DWORD winapi workproc (_ in lpvoid lpparameter) {DWORD dwthreadid = getcurrentthreadid (); int I = (INT) lpparameter; printf ("thread: % d, time: % d, VAL: % d \ n ", dwthreadid, gettickcount (), I); return 1;} void workitemdemo () {for (INT I = 0; I <100; I ++) {queueuserworkitem (workproc, (pvoid) I, wt_executedefault );}}
2) timed callback function
Applicable to scenarios where the timer needs to be started without affecting the main thread
Void callback timerroutine (pvoid lpparam, Boolean timerorwaitfired) {If (lpparam = NULL) {printf ("timerroutine lpparam is null \ n");} else {printf ("thread: % d timer routine called. parameter is % d. \ n ", getcurrentthreadid (), * (int *) lpparam) ;}} int _ tmain (INT argc, _ tchar * argv []) {handle htimer [10]; handle htimerqueue = NULL; int Arg = 123; // create the timer queue. htimerqueue = createtimerqueue (); If (null = Htimerqueue) {printf ("createtimerqueue failed (% d) \ n", getlasterror (); return 2;} int iarray [10] = {, 6, 7, 8, 9}; For (INT I = 0; I <10; I ++) {// set a timer to call the timer routine in 10 seconds. if (! Callback (htimer + I, htimerqueue, (waitortimercallback) timerroutine, iarray + I, 100 + I * 100,100, 0) {printf ("createtimerqueuetimer failed (% d) \ n ", getlasterror (); return 3 ;}// todo: Do other useful work here // waitformultipleobjects (10, htimer, true, infinite); sleep (60*1000 ); printf ("Call timer routine in 10 seconds... \ n "); // delete all timers in the timer queue. if (! Deletetimerqueue (htimerqueue) printf ("deletetimerqueue failed (% d) \ n", getlasterror (); Return 0 ;}
3) Kernel Object notification Status callback
This method is applicable to multiple threads waiting for a notification of the same kernel object. The same wait event can be accessed by multiple callbacks at the same time, and can be called multiple times when the object is in the notification Status ....
Void callback waitortimercallback0 (_ in pvoid lpparameter ,__ in Boolean timerorwaitfired) {// The Notification status automatically calls static volatile long icount = 0; int I = (INT) lpparameter; interlockedincrement (& icount); printf ("thread: % d, VAL: % d, Count: % d \ n", getcurrentthreadid (), I, icount );} //... registerwaitforsingleobject (& HREG [0], hevent, waitortimercallback0, 0,100, wt_executedefault );//... Setevent (hevent );//... Unregisterwait (HREG [0]);
4) Call the function when the asynchronous Io request is completed
Note that the overlapping mode is used to create and read/write files. getoverlappedresult must be called to read/write data.
DWORD g_dwwriten = 0; void callback myfileiocompletionroutine (_ in DWORD dwerrorcode ,__ in DWORD contains ,__ in lpoverlapped) {printf ("thread: % d, Trans: % d \ n ", getcurrentthreadid (), dwnumberofbytestransfered );}//... Hfile = createfile (pszfile, // name of the writegeneric_write, // open for writing0, // do not sharenull, // default securitycreate_always, // overwrite writable | file_flag_overlapped, // file_flag_overlapped overlapping mode null );//... Overlapped ov; zeromemory (& ov, sizeof (overlapped); If (false = writefile (hfile, // open file handledatabuffer + dwbyteswritten, // start of data to writedwbytestowrite-dwbyteswritten, // number of bytes to write & dwbyteswritten, // number of bytes that were written & OV) // overlapped overlap Mode) {If (getlasterror ()! = Error_io_pending) {printf ("cocould not write to file (error % d) \ n", getlasterror (); closehandle (hfile); Return 0;} getoverlappedresult (hfile, & ov, & dwbyteswritten, true );}