C ++ implementation thread pool in vc6.0

Source: Internet
Author: User

In the project, because mobile devices need to request services from the management center, the management center uses the concurrency mode to process requests (corresponding to the polling mode ), because a thread needs to be created to provide services for the corresponding requests each time a connection is established, threads need to be created frequently, and the threads need to be destroyed when the service ends or the connection is disconnected, such a process is costly to the system. In addition, other modules in the Management Center also need to frequently enable and destroy threads. In order to make the system more stable, we decided to add a thread pool.

However, all threads are created in the C ++ class. As you see, there are restrictions on creating threads in the C ++ class. To keep the code written to the minimum, I processed the thread pool Code widely circulated on the Internet (so far I have not found an example that can run smoothly and be used directly) to meet the requirements of our project. It is still being tested, so far there have been no problems. Upload and share with you, learn from each other, and communicate with each other.

The explanation of the Code has not been written yet. I am not sure whether you need it or not, and I am also busy recently, so I am a little lazy.

In vc6.0, C ++ implements the complete project of the thread pool and DLL encapsulation:

Http://download.csdn.net/detail/pinghegood/4909203

* 2012.12.17 modify a bug

Catch (...){

// M_functionandparammutex.lock (); // a deadlock may occur.
Trace0 ("process job error! ");
}

* 2.12.12.19 modify a bug

Bool cworkerthread: Terminate () {// handle temphandle = getthreadhandle (); // trace0 ("current thread terminate \ n"); m_threadrunflagmutex.lock (); m_threadrunflag = false; m_threadrunflagmutex.unlock (); resumethread (m_threadhandle); int ret; ret =: waitforsingleobject (m_threadhandle, 1); If (wait_object_0! = RET) // you need to determine whether to force the end of {DWORD dwexitcode; getexitcodethread (m_threadhandle, & dwexitcode); terminatethread (m_threadhandle, dwexitcode) based on the return value );:: closehandle (m_threadhandle);} m_threadhandle = NULL; return true ;}

April: note that the submitted task functions should use the standard call method winapi.

June: A Bug was modified. cthreadmanage failed to call the default constructor.

Delete cthreadmanage: cthreadmanage () and set the default value for the constructor with parameters. See http://blog.csdn.net/pinghegood/article/details/8745568 for specific reasons

Thread Pool instructions (Supplement on June 12)

One-thread pool application environment:

Thread pools are generally used for network server programs. The server programs mentioned here refer to the programs that can accept client requests and process requests, not just network server programs that accept requests from network customers.

Multithreading technology mainly solves the problem of multiple threads in a processor unit. It can significantly reduce the idle time of the processor unit and increase the throughput of the processor unit. However, improper multi-threaded application will increase the processing time for a single task. Here is a simple example:

Assume that the time for completing a task on a server is t

Time when T1 was created

Task execution time in T2 thread, including the time required for Inter-Thread Synchronization

Time when the T3 thread is destroyed

Obviously T = t1 + T2 + T3. Note that this is an extremely simplified assumption.

We can see that T1 and T3 are the overhead of multithreading itself. We are eager to reduce the time consumed by T1 and T3, thus reducing t time. But some threads do not notice this, So threads are frequently created or destroyed in the program, which leads to a considerable proportion of T1 and t3 in T. Obviously this highlights the thread's weakness (T1, T3), rather than the advantage (concurrency ).

The thread pool technology focuses on how to shorten or adjust T1 and T3 time to improve the performance of server programs. It arranges T1 and t3 in the start and end time periods or some idle time periods of the server program, so that when the server program processes customer requests, there will be no overhead of T1 and T3.

The thread pool not only adjusts the time periods generated by T1 and T3, but also significantly reduces the number of created threads. Let's look at an example:

Assume that a server processes 50000 requests a day, and each request requires a separate thread. We compare the total number of threads produced when the server that uses the thread pool technology and is not conducive to the thread pool technology processes these requests. In the thread pool, the number of threads is generally fixed, so the total number of threads generated will not exceed the number or upper limit of threads in the thread pool (hereinafter referred to as the thread pool size ), if the server does not use the thread pool to process these requests, the total number of threads is 50000. Generally, the thread pool size is much smaller than 50000. Therefore, the server program that uses the thread pool does not waste time processing to create 50000 requests, thus improving efficiency.

Although the thread pool can reduce system overhead and increase system stability, not all threads can be used. Specifically, the thread pool should not be used in the following situations:

(1) If a thread may run for a long time (and thus block other tasks;

(2) If you need a permanent identifier to identify and control the thread, for example, you want to use a dedicated thread to terminate the thread, because it cannot be determined when the thread pool allocates the thread to execute the task. Theoretically, every thread of a task has the opportunity to be allocated for execution. However, the specific thread that executes the task depends on the status of the thread in the thread pool at that time.

(3) give a task a specific priority. This is not suitable for thread pools, because the processing of tasks in the thread pool is in FIFO mode, the only task priority that can be set is that the task can be inserted into the team header rather than the team end when a task is added.

Ii. How to Use C ++ to implement a custom thread pool (the important functions in the main class are described below)

In my project, the thread pool is mainly used to receive and process client requests. After the corresponding processing is completed, the connection with the client will be disconnected, so it meets the usage of the thread pool. Specifically, the thread pool used includes the following classes:

2.1 cthreadmanage class:

Interface Class for external calls. The only interface class in the thread pool that is provided to external users for operation.

Method:

(1) bool addjob (jobcallbacke callbackfunction, lpvoid lpparam, intparamsize, jobpriority) Throw (string)

Function: The addjob method submits user processing tasks to the task queue in the thread pool for _ dispensejobthread to add them to the thread pool for execution. If an exception occurs when a task is added, the function throws a cthreadpoolexception type exception.

Parameter description:

Callbackfunction: The task callback function pointer, which corresponds to the User-Defined processing logic (note that the submitted task function must use the standard call method winapi ).

Lpparam: The parameter pointer passed to the task callback function.

Paramsize: The parameter size passed to the task callback function (measured using sizeof ).

Jobpriority: determines the priority of the task. Here we only have two priority modes: high_priority and normal_priority. When high_priority is specified, the task is added to the team header. If normal_priority is specified, the task is added to the team end.

(2) void terminateall (void)

Function: Use the terminateall method to terminate the task distribution thread _ dispensejobthread and call the terminateall () of the cthreadpool class (). In the end, the entire thread pool will be safely ended.

(3) getjob (jobinfo * lpjob)

Function: getjob method, which extracts a task from the header of the m_joblist queue.

2.2 cthreadpool class:

The thread pool management class is responsible for managing the busy thread queues and idle thread queues in the thread pool. The cthreadpool class maintains two thread Queues: m_busylist and m_idlelist. At the beginning, the pre-generated thread object pointers are stored in m_idlelist. When a thread is assigned a task, it is transferred from m_idlelist to m_busylist. Due to the multi-thread synchronization problem, we use m_availnum to calculate the number of Idle threads instead of the m_idlelist size.

Method:

(1) cworkerthread * getidlethread (void)

Function: extracts an idle thread from the idle queue of the thread pool.

(2) void appendtoidlelist (cworkerthread * jobthread)

Function: adds the created thread to the idle queue of the thread pool.

Parameter description: jobthread is a pointer to a thread object.

(3) void movetobusylist (cworkerthread * jobthread)

Function: After the task is assigned to the corresponding thread, put the thread object pointed to by jobthread into the busy queue.

Parameter description: jobthread is a pointer to a thread object to be executed.

(4) void movetoidlelist (cworkerthread * busythread );

Function: After a thread executes a user task, it is re-added to the idle thread queue.

Parameter description: busythread is a thread pointer to the task to be completed.

(5) void deleteidlethread (intnum );

Function: when the number of Idle threads exceeds m_availhigh, the number of Idle threads of num is terminated, so that the number of Idle threads remains between m_availlow and m_availhigh.

Parameter description: num knows the number of Idle threads to end

(6) void createidlethread (intnum );

Function: Creates num Idle threads and adds them to the idle queue of the thread pool.

Parameter description: num indicates the number of Idle threads to be created.

2.3 cthread class:

CthreadClass isCworkerthreadClass Parent class is a pure virtual class, responsible for creating threads in the thread pool and Executing User call operations

(1) handle cthread: Start (cthread * cthread)

Function: Create an idle thread that calls _ threadfunction and then callsCworkerthreadWhen the first run () function is executed, suspendthread is called to suspend the thread. It will not be wakened again until a task is assigned to the thread or the thread is terminated.

Parameter description: cthread pointsCworkerthreadThread object pointer

(2) Static DWORD winapi _ threadfunction (lpvoid lpparam );

Function: callback function in the thread pool.

Parameter description: lpparam indicatesCworkerthreadThread object pointer

(3) virtual void run () = 0;

Function function: the actual execution function of the thread in the thread pool. Run () is a pure virtual function that needs to be re-implemented in every subclass of cthread.

2.4 cworkerthread class:

The thread execution function provider in the thread pool is responsible for calling user callback functions and cleaning after User Function calls are completed.

(1) bool cworkerthread: setjob (jobinfo tempjobinfo)

Function: Call the run () function of the cthreadpool to set information about the user callback function to the execution thread. After the thread is awakened, the set callback function will be executed.

Parameter description: User callback function information of tempjobinfo, including callback function pointer, callback function parameter pointer, and parameter size

(2) void cworkerthread: Run ()

Function: The function actually called when the thread is running in the thread pool. In this function, the corresponding callback function is called Based on the setjob settings.

(3) bool cworkerthread: Terminate ()

Function: end a thread. It is called when the thread pool ends or the thread needs to be terminated.

Three main struct

3.1 Structure of callback function information:

Typedefstruct tagjobinfo {// callback function pointer and Parameters

Jobcallbacke jobcallback;

Unsigned char * lpparam;

Unsigned int length;

} Jobinfo;

3.2 thread priority Mechanism

Typedefenum tagjobpriority // thread priority

{

High_priority,

Normal_priority

} Jobpriority;

Four types of charts

Figure 1: thread pool class diagram

 

Workflow of five thread pools

Figure 2: thread pool processing Flowchart

The general process description of the thread pool calling mechanism is provided here. The detailed process should be carefully studied in conjunction with the engineering code.

6. How to add a thread pool to an existing C ++ Project

First, copy the header file to the prepared C ++ project folder, and copy the DLL file to the DEBUG directory (if you directly add the CPP file to the project, you do not need to copy the DLL file ).

Then, include the threadmanage. h header file in the file to be used and define the cthreadmanage object in the corresponding class.

Finally, annotate the code of the previously created thread and use the cthreadmanage object to call the addjob () function. Add winapi before the declaration of the callback function to change the calling method. Call terminateall (void) in the destructor of this class to end the thread pool at the end of the program.

To sum up, you can add a thread pool on the basis of maintaining the minimum modification of the original C ++ code.

7. Problem feedback

Please contact 772319357@qq.com if you have any questions

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.