Thread Pool analysis and C ++ code implementation

Source: Internet
Author: User
Tags failover

Thread Pool analysis and C ++ code implementation

(1) What is a thread pool?

Thread pool is a multi-thread processing technology. Several threads are created in the thread pool and managed. When a new task arrives, add the task to a created idle thread for execution. The thread pool has the same priority. Therefore, it is not recommended that you use a thread pool for tasks with a specific thread priority.

(2) advantages and applications of the thread pool

The thread pool manages threads in a unified manner, which reduces the System Scheduling overhead for frequent thread creation and destruction, and greatly improves the server's performance in processing concurrent tasks.

The thread pool is suitable for frequent task scheduling, such as handling HTTP requests, multiple tasks, and a small task cycle.

(3) c ++ code implementation

# Include "stdafx. H"

 

# Include "stdafx. H"

# Include <assert. h>

# Include <windows. h>

# Include <map>

# Include <iostream>

 

Using namespace STD;

 

Class itask

{

Public:

Virtual void processtask (void * puser) = 0;

};

// Failover pool

Class cthreadpool

{

Public:

Class threadinfo

{

Public:

Threadinfo () {m_hthread = 0; m_bbusyworking = false ;}

Threadinfo (handlehandle, boolbbusy) {m_hthread = handle; m_bbusyworking = bbusy ;}

Threadinfo (const threadinfo & info) {m_hthread = info. m_hthread; m_bbusyworking = info. m_bbusyworking ;}

Handle m_hthread;

Bool m_bbusyworking;

};

 

Typedef Map <DWORD, threadinfo> threadinfomap;

Typedef threadinfomap: iterator iterator_threadinfomap;

 

Enum threadpoolstatus {status_busy, status_idle, status_normal };

Public:

Cthreadpool ()

{

Initializecriticalsection (& m_cs );

}

Virtual ~ Cthreadpool ()

{

Deletecriticalsection (& m_cs );

}

 

Bool start (unsigned short nstatic, unsigned short Nmax)

{

If (Nmax <nstatic)

{

Assert (0 );

Return false;

}

Handle hthread;

DWORD nthreadid;

M_nnumberofstaticthreads = nstatic;

M_nnumberoftotalthreads = Nmax;

 

// Lock the resource

Entercriticalsection (& m_cs );

 

// Create an IO port

M_hmrioport = createiocompletionport (handle) invalid_handle_value, null, 0, 0 );

Hthread = createthread (

Null, // SD

0, // initial stack size

(Lpthread_start_routine) managerproc, // threadfunction

(Lpvoid) This, // thread argument

0, // creationoption

& Nthreadid); // thread identifier

M_hmgrthread = hthread;

 

// Now we start these worker threads

M_hworkerioport = createiocompletionport (handle) invalid_handle_value, null, 0, 0 );

For (long n = 0; n <nstatic; n ++)

{

Hthread = createthread (

Null, // SD

0, // initial stack size

(Lpthread_start_routine) workerproc, // threadfunction

(Lpvoid) This, // thread argument

0, // creation Option

& Nthreadid );

M_threadmap.insert (m_threadmap.end (), threadinfomap: value_type (nthreadid, threadinfo (hthread, false )));

}

 

Leavecriticalsection (& m_cs );

Return true;

}

 

Void stop (bool bhash = false)

{

Entercriticalsection (& m_cs );

 

: Postqueuedcompletionstatus (m_hmrioport, 0, 0, (overlapped *) 0 xffffff );

Waitforsingleobject (m_hmgrthread, infinite );

Closehandle (m_hmgrthread );

Closehandle (m_hmrioport );

 

// Shut down all the worker threads

Uint ncount = m_threadmap.size ();

Handle * pthread = new handle [ncount];

Long n = 0;

Threadinfo Info;

Iterator_threadinfomap I = m_threadmap.begin ();

While (I! = M_threadmap.end ())

{

: Postqueuedcompletionstatus (m_hworkerioport, 0, 0, (overlapped *) 0 xffffffff );

Info = I-> second;

Pthread [n ++] = info. m_hthread;

I ++;

}

 

DWORD rc = waitformultipleobjects (ncount, pthread, true, 30000); // wait for 0.5 minutes, then start to killthreads

Closehandle (m_hworkerioport );

If (rc> = wait_object_0 & rc <wait_object_0 + ncount)

{

For (unsigned int n = 0; n <ncount; n ++)

{

Closehandle (pthread [N]);

}

}

Else if (rc = wait_timeout & bhash)

{

// Some threadsnot terminated, we have to stop them.

DWORD exitcode;

For (unsigned int I = 0; I <ncount; I ++)

{

If (: getexitcodethread (pthread [I], & exitcode) = still_active)

{

Terminatethread (pthread [I], 99 );

}

Closehandle (pthread [I]);

}

}

Delete [] pthread;

 

Leavecriticalsection (& m_cs );

}

 

Void addtask (void * puser, itask * pworker) const

{

: Postqueuedcompletionstatus (m_hworkerioport ,\

Reinterpret_cast <DWORD> (pworker ),\

Reinterpret_cast <DWORD> (puser ),\

Null );

}

 

Protected:

Handle getmgrioport () const {return m_hmrioport ;}

Uint getmgrwaittime () const {return1000 ;}

Handle getworkerioport () const {return m_hworkerioport ;}

 

PRIVATE:

Static DWORD winapi workerproc (void * P)

{

// Convert the parameter to the server pointer.

Cthreadpool * pserver = (cthreadpool *) P;

Handle ioport = pserver-> getworkerioport ();

Unsigned long pn1, pn2;

Overlapped * poverlapped;

 

DWORD threadid =: getcurrentthreadid ();

 

While (: getqueuedcompletionstatus (ioport, & pn1, & pn2,

& Poverlapped, infinite ))

{

If (poverlapped = (overlapped *) 0 xfffffffe)

{

Pserver-> removethread (threadid );

Break;

}

Else if (poverlapped = (overlapped *) 0 xffffffff)

{

Break;

}

Else

{

Pserver-> setstatus (threadid, true );

// Retrieve the job description and Agent pointer

Itask * ptask = reinterpret_cast <itask *> (pn1 );

Void * puser = reinterpret_cast <void *> (pn2 );

Ptask-> processtask (puser );

Pserver-> setstatus (threadid, false );

}

}

Return 0;

}

 

 

Static DWORD winapi managerproc (void * P)

{

// Convert the parameter to the server pointer.

Cthreadpool * pserver = (cthreadpool *) P;

Handle ioport = pserver-> getmgrioport ();

Unsigned long pn1, pn2;

Overlapped * poverlapped;

 

Label_manager_processing:

While (: getqueuedcompletionstatus (ioport, & pn1, & pn2,

& Poverlapped, pserver-> getmgrwaittime ()))

{

If (poverlapped = (overlapped *) 0 xffffffff)

{

Return 0;

}

}

 

// Time Out Processing

If (: getlasterror () = wait_timeout)

{

// The manager will take a look at all the worker's status.

If (pserver-> getstatus () = status_busy)

Pserver-> addthreads ();

If (pserver-> getstatus () = status_idle)

Pserver-> removethreads ();

 

Goto label_manager_processing;

}

Return 0;

}

 

Protected:

// Manager thread

Handle m_hmgrthread;

Handle m_hmrioport;

Protected:

// Configuration parameters

Mutable unsigned short m_nnumberofstaticthreads;

Mutable unsigned short m_nnumberoftotalthreads;

 

Protected:

// Helper functions

Void cthreadpool: addthreads ()

{

Handle hthread;

DWORD nthreadid;

Unsigned int ncount = m_threadmap.size ();

Unsigned int ntotal = min (ncount + 2, m_nnumberoftotalthreads );

For (unsigned int I = 0; I <ntotal-ncount; I ++)

{

Hthread = createthread (

Null, // SD

0, // initial stack size

(Lpthread_start_routine) workerproc, // threadfunction

(Lpvoid) This, // thread argument

0, // creation Option

& Nthreadid );

 

M_threadmap.insert (m_threadmap.end (), threadinfomap: value_type (nthreadid, threadinfo (hthread, false )));

}

}

 

Void removethreads ()

{

Unsigned int ncount = m_threadmap.size ();

Unsigned int ntotal = max (nCount-2, m_nnumberofstaticthreads );

For (unsigned int I = 0; I <ncount-ntotal; I ++)

{

: Postqueuedcompletionstatus (m_hworkerioport, 0, 0, (overlapped *) 0 xfffffe );

}

}

 

Threadpoolstatus getstatus ()

{

Int ntotal = m_threadmap.size ();

Threadinfo Info;

Int ncount = 0;

Iterator_threadinfomap I = m_threadmap.begin ();

While (I! = M_threadmap.end ())

{

Info = I-> second;

If (info. m_bbusyworking = true) ncount ++;

I ++;

}

If (ncount/(1.0 * ntotal)> 0.8)

Return status_busy;

If (ncount/(1.0 * ntotal) <0.2)

Return status_idle;

Return status_normal;

}

 

Void setstatus (DWORD threadid, bool status)

{

Entercriticalsection (& m_cs );

 

Iterator_threadinfomap I;

Threadinfo Info;

I = m_threadmap.find (threadid );

Info = I-> second;

Info. m_bbusyworking = status;

M_threadmap.insert (m_threadmap.end (), threadinfomap: value_type (threadid, Info ));

 

Leavecriticalsection (& m_cs );

}

 

Void cthreadpool: removethread (dwordthreadid)

{

Entercriticalsection (& m_cs );

M_threadmap.erase (threadid );

Leavecriticalsection (& m_cs );

}

 

Protected:

// All the work threads

Threadinfomap m_threadmap;

Critical_section m_cs;

Handle m_hworkerioport;

};

 

//// // The original generation of the latest version //////////////// ////////////////////

Class ctest: Public itask

{

Public:

Ctest ()

{

Static int II = 0;

M_ii = II ++;

}

 

Void processtask (void * puser)

{

For (INT I = 0; I <3; I ++)

{

Cout <"taskid:" <(ctest *) puser)-> m_ii <Endl;

Sleep (100 );

}

 

}

 

~ Ctest ()

{

 

}

PRIVATE:

Int m_ii;

};

 

Int _ tmain (INT argc, _ tchar * argv [])

{

Cthreadpool * ppool = new cthreadpool ();

Const int test_count = 8;

Ctest test [test_count];

// Dynamic Route pool, with 5 processing routes and a maximum of 10 tasks

Ppool-> Start (5, 10 );

 

// Add tasks to the scheduler pool

For (INT I = 0; I <test_count; I ++)

Ppool-> addtask (& test [I], & test [I]);

Cin. Get ();

// Stop the Failover pool

Ppool-> stop ();

 

Return 0;

}

 

 

 

Related Article

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.