⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 月光软件站 - 编程文档 - vc语言 - 一个好用的线程池.mht

📁 线程池的源码模压可耕地可耕地枯可耕地在村枯枯枯要要要求
💻 MHT
📖 第 1 页 / 共 5 页
字号:
            p);<BR>&nbsp;static DWORD WINAPI WorkerProc(void*=20
            p);<BR>protected:<BR>&nbsp;//manager thread<BR>&nbsp;HANDLE=20
            m_hMgrThread;<BR>&nbsp;HANDLE=20
            m_hMgrIoPort;<BR>protected:<BR>&nbsp;//configuration=20
            parameters<BR>&nbsp;mutable unsigned short=20
            m_nNumberOfStaticThreads;<BR>&nbsp;mutable unsigned short=20
            m_nNumberOfTotalThreads;</P>
            <P>protected:<BR>&nbsp;//helper functions<BR>&nbsp;void=20
            AddThreads();<BR>&nbsp;void=20
            RemoveThreads();<BR>&nbsp;ThreadPoolStatus=20
            GetThreadPoolStatus();<BR>&nbsp;void ChangeStatus(DWORD =
threadId,=20
            bool status);<BR>&nbsp;void RemoveThread(DWORD =
threadId);</P>
            <P>protected:<BR>&nbsp;//all the work =
threads<BR>&nbsp;ThreadInfoMap=20
            m_threadMap;<BR>&nbsp;CCriticalSection =
m_arrayCs;<BR>&nbsp;HANDLE=20
            m_hWorkerIoPort;<BR>};</P>
            <P>#endif //=20
            =
!defined(AFX_THREADPOOLIMP_H__82F4FC7E_2DB4_4D2A_ACC8_2EFC787CAE42__INCLU=
DED_)<BR><BR><BR>=CA=B5=CF=D6=C8=E7=CF=C2<BR><BR><BR>//=20
            ThreadPool.cpp: implementation of the CThreadPoolImp=20
            =
class.<BR>//<BR>/////////////////////////////////////////////////////////=
/////////////</P>
            <P>#include "stdafx.h"<BR>#include =
"ThreadPoolimp.h"<BR>#include=20
            "outdebug.h"<BR>#include &lt;assert.h&gt;<BR>#include =
"work.h"</P>
            <P>#ifdef _DEBUG<BR>#undef THIS_FILE<BR>static char=20
            THIS_FILE[]=3D__FILE__;<BR>//#define new =
DEBUG_NEW<BR>#endif</P>
            <P>CThreadPoolImp::CThreadPoolImp()<BR>{<BR>}</P>
            <P>CThreadPoolImp::~CThreadPoolImp()<BR>{</P>
            <P>}</P>
            <P>void CThreadPoolImp::Start(unsigned short nStatic, =
unsigned short=20
            =
nMax)<BR>{<BR>&nbsp;assert(nMax&gt;=3DnStatic);<BR>&nbsp;HANDLE&nbsp;=20
            =
hThread;<BR>&nbsp;DWORD&nbsp;nThreadId;<BR>&nbsp;m_nNumberOfStaticThreads=
=3DnStatic;<BR>&nbsp;m_nNumberOfTotalThreads=3DnMax;</P>
            <P>&nbsp;//lock the resource<BR>&nbsp;CAutoLock=20
            AutoLock(m_arrayCs);</P>
            <P>&nbsp;//create an IO port<BR>&nbsp;m_hMgrIoPort =3D=20
            CreateIoCompletionPort((HANDLE)INVALID_HANDLE_VALUE, NULL, =
0,=20
            0);<BR>&nbsp;hThread =3D=20
            CreateThread(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
NULL, //=20
            SD<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
            =
0,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
            // initial stack =
size<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
            (LPTHREAD_START_ROUTINE)ManagerProc,&nbsp;&nbsp;&nbsp; // =
thread=20
            function<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
            =
(LPVOID)this,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =

            // thread =
argument<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
            =
0,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
            // creation =
option<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
            &amp;nThreadId=20
            =
);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
            // thread identifier<BR>&nbsp;m_hMgrThread =3D hThread;</P>
            <P>&nbsp;//now we start these worker=20
            threads<BR>&nbsp;m_hWorkerIoPort =3D=20
            CreateIoCompletionPort((HANDLE)INVALID_HANDLE_VALUE, NULL, =
0,=20
            0);<BR>&nbsp;for(long n =3D 0; n &lt; nStatic;=20
            n++)<BR>&nbsp;{<BR>&nbsp;&nbsp;hThread =3D=20
            CreateThread(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
NULL, //=20
            SD<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
            =
0,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
            // initial stack =
size<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
            (LPTHREAD_START_ROUTINE)WorkerProc,&nbsp;&nbsp;&nbsp; // =
thread=20
            function<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
            =
(LPVOID)this,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =

            // thread =
argument<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
            =
0,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
            // creation =
option<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
            &amp;nThreadId );&nbsp;&nbsp;&nbsp;=20
            <BR>&nbsp;&nbsp;ReportDebug("generate a worker thread handle =
id is=20
            %d.\n",=20
            =
nThreadId);<BR>&nbsp;&nbsp;m_threadMap.insert(m_threadMap.end(),ThreadInf=
oMap::value_type(nThreadId,ThreadInfo(hThread,=20
            false)));<BR>&nbsp;}<BR>}</P>
            <P>void CThreadPoolImp::Stop(bool =
bHash)<BR>{<BR>&nbsp;CAutoLock=20
            Lock(m_arrayCs);</P>
            <P>&nbsp;::PostQueuedCompletionStatus(m_hMgrIoPort, 0, 0,=20
            =
(OVERLAPPED*)0xFFFFFFFF);<BR>&nbsp;WaitForSingleObject(m_hMgrThread,=20
            =
INFINITE);<BR>&nbsp;CloseHandle(m_hMgrThread);<BR>&nbsp;CloseHandle(m_hMg=
rIoPort);</P>
            <P>&nbsp;//shut down all the worker threads<BR>&nbsp;UINT=20
            nCount=3Dm_threadMap.size();<BR>&nbsp;HANDLE* pThread =3D =
new=20
            HANDLE[nCount];<BR>&nbsp;long n=3D0;<BR>&nbsp;ThreadInfo=20
            info;<BR>&nbsp;Iterator_ThreadInfoMap=20
            =
i=3Dm_threadMap.begin();<BR>&nbsp;while(i!=3Dm_threadMap.end())<BR>&nbsp;=
{<BR>&nbsp;&nbsp;::PostQueuedCompletionStatus(m_hWorkerIoPort,=20
            0, 0,=20
            =
(OVERLAPPED*)0xFFFFFFFF);<BR>&nbsp;&nbsp;info=3Di-&gt;second;<BR>&nbsp;&n=
bsp;pThread[n++]=3Dinfo.m_hThread;<BR>&nbsp;&nbsp;i++;<BR>&nbsp;}</P>
            <P>&nbsp;DWORD rc=3DWaitForMultipleObjects(nCount, pThread, =
TRUE,=20
            30000);//wait for 0.5 minutes, then start to kill=20
            =
threads<BR>&nbsp;CloseHandle(m_hWorkerIoPort);<BR>&nbsp;if(rc&gt;=3DWAIT_=
OBJECT_0=20
            &amp;&amp;=20
            =
rc&lt;WAIT_OBJECT_0+nCount)<BR>&nbsp;{<BR>&nbsp;&nbsp;for(unsigned=20
            int=20
            =
n=3D0;n&lt;nCount;n++)<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;CloseHandle(=
pThread[n]);<BR>&nbsp;&nbsp;}<BR>&nbsp;}<BR>&nbsp;else=20
            =
if(rc=3D=3DWAIT_TIMEOUT&amp;&amp;bHash)<BR>&nbsp;{<BR>&nbsp;&nbsp;//some =

            threads not terminated, we have to stop =
them.<BR>&nbsp;&nbsp;DWORD=20
            exitCode;<BR>&nbsp;&nbsp;for(unsigned int i=3D0; =
i&lt;nCount;=20
            i++)<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;if=20
            (::GetExitCodeThread(pThread[i],=20
            =
&amp;exitCode)=3D=3DSTILL_ACTIVE)<BR>&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&=
nbsp;&nbsp;TerminateThread(pThread[i],=20
            =
99);<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;CloseHandle(pThread[i]);=
<BR>&nbsp;&nbsp;}<BR>&nbsp;}<BR>&nbsp;delete[]=20
            pThread;<BR>}</P>
            <P>DWORD WINAPI CThreadPoolImp::ManagerProc(void*=20
            p)<BR>{<BR>&nbsp;//convert the parameter to the server=20
            pointer.<BR>&nbsp;CThreadPoolImp*=20
            =
pServer=3D(CThreadPoolImp*)p;<BR>&nbsp;HANDLE&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;IoPort&nbsp;=3D=20
            pServer-&gt;GetMgrIoPort();<BR>&nbsp;unsigned=20
            long&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pN1, pN2;=20
            =
<BR>&nbsp;OVERLAPPED*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pOverLappe=
d;</P>
            =
<P>LABEL_MANAGER_PROCESSING:<BR>&nbsp;while(::GetQueuedCompletionStatus(I=
oPort,=20
            &amp;pN1, &amp;pN2, <BR>&nbsp;&nbsp;&amp;pOverLapped,=20
            pServer-&gt;GetMgrWaitTime()=20
            ))<BR>&nbsp;{<BR>&nbsp;&nbsp;if(pOverLapped =3D=3D=20
            =
(OVERLAPPED*)0xFFFFFFFF)<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;return=20
            0;<BR>&nbsp;&nbsp;}<BR>//&nbsp;&nbsp;else if(pOverLapped =
=3D=3D=20
            =
(OVERLAPPED*)0xFFFFFFFE)<BR>//&nbsp;&nbsp;{<BR>//&nbsp;&nbsp;&nbsp;if(pN1=
!=3D0)<BR>//&nbsp;&nbsp;&nbsp;{<BR>//&nbsp;&nbsp;&nbsp;&nbsp;DWORD=20
            =
rc=3D::WaitForSingleObject((HANDLE)pN1,INFINITE);<BR>//&nbsp;&nbsp;&nbsp;=
&nbsp;if(rc=3DWAIT_OBJECT_0)<BR>//&nbsp;&nbsp;&nbsp;&nbsp;{<BR>//&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;CloseHandle((HANDLE)pN1);//=B9=D8=B1=D5=B8=C3=CF=DF=
=B3=CC=BE=E4=B1=FA<BR>//&nbsp;&nbsp;&nbsp;&nbsp;}<BR>//&nbsp;&nbsp;&nbsp;=
&nbsp;ReportDebug("Wait=20
            a Thread=20
            =
Removed!\n");<BR>//&nbsp;&nbsp;&nbsp;}<BR>//&nbsp;&nbsp;}<BR>&nbsp;&nbsp;=
else=20
            <BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;ReportDebug("mgr =
events comes=20
            in!\n");<BR>&nbsp;&nbsp;}<BR>&nbsp;}</P>
            <P>&nbsp;//time out processing<BR>&nbsp;if=20
            =
(::GetLastError()=3D=3DWAIT_TIMEOUT)<BR>&nbsp;{<BR>&nbsp;&nbsp;//time=20
            out processing<BR>&nbsp;&nbsp;ReportDebug("Time out=20
            processing!\n");<BR>&nbsp;&nbsp;//the manager will take a =
look at=20
            all the worker's status. The<BR>&nbsp;&nbsp;if=20
            =
(pServer-&gt;GetThreadPoolStatus()=3D=3DCThreadPoolImp::BUSY)<BR>&nbsp;&n=
bsp;&nbsp;pServer-&gt;AddThreads();<BR>&nbsp;&nbsp;if=20
            =
(pServer-&gt;GetThreadPoolStatus()=3D=3DCThreadPoolImp::IDLE)<BR>&nbsp;&n=
bsp;&nbsp;pServer-&gt;RemoveThreads();</P>
            <P>&nbsp;&nbsp;goto=20
            LABEL_MANAGER_PROCESSING;<BR>&nbsp;}<BR>&nbsp;return =
0;<BR>}</P>
            <P>DWORD WINAPI CThreadPoolImp::WorkerProc(void*=20
            p)<BR>{<BR>&nbsp;//convert the parameter to the server=20
            pointer.<BR>&nbsp;CThreadPoolImp*=20
            =
pServer=3D(CThreadPoolImp*)p;<BR>&nbsp;HANDLE&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;IoPort&nbsp;=3D=20
            pServer-&gt;GetWorkerIoPort();<BR>&nbsp;unsigned=20
            long&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pN1, pN2;=20
            =
<BR>&nbsp;OVERLAPPED*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pOverLappe=
d;</P>
            <P>&nbsp;DWORD=20
            =
threadId=3D::GetCurrentThreadId();<BR>&nbsp;ReportDebug("worker thread=20
            id is %d.\n", threadId);</P>
            <P>&nbsp;while(::GetQueuedCompletionStatus(IoPort, &amp;pN1, =

            &amp;pN2, <BR>&nbsp;&nbsp;&amp;pOverLapped, INFINITE=20
            ))<BR>&nbsp;{<BR>&nbsp;&nbsp;if(pOverLapped =3D=3D=20
            (OVERLAPPED*)0xFFFFFFFE)<BR>&nbsp;&nbsp;{</P>
            =
<P>//&nbsp;&nbsp;&nbsp;CThreadPoolImp::Iterator_ThreadInfoMap=20
            =
it=3DpServer-&gt;m_threadMap.find(threadId);<BR>//&nbsp;&nbsp;&nbsp;if(it=
!=3DpServer-&gt;m_threadMap.end())<BR>//&nbsp;&nbsp;&nbsp;{<BR>//&nbsp;&n=
bsp;&nbsp;&nbsp;::PostQueuedCompletionStatus(pServer-&gt;m_hMgrIoPort,<BR=
>//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(unsigned=20
            =
long)it-&gt;second.m_hThread,<BR>//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0,=20
            =
<BR>//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(OVERLAPPED*)0xFFFFFFFE);<BR>&nbsp;&n=
bsp;&nbsp;&nbsp;pServer-&gt;RemoveThread(threadId);<BR>//&nbsp;&nbsp;&nbs=
p;&nbsp;ReportDebug("Try=20
            to Remove a=20
            =
Thread\n");<BR>//&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;break;<BR=
>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;else=20
            if(pOverLapped =3D=3D=20
            =
(OVERLAPPED*)0xFFFFFFFF)<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;break;<BR>=
&nbsp;&nbsp;}<BR>&nbsp;&nbsp;else<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;R=
eportDebug("worker=20
            events comes in!\n");<BR>&nbsp;&nbsp;&nbsp;//before =
processing, we=20
            need to change the status to=20
            =
busy.<BR>&nbsp;&nbsp;&nbsp;pServer-&gt;ChangeStatus(threadId,=20
            true);<BR>&nbsp;&nbsp;&nbsp;//retrieve the job description =
and agent=20
            pointer<BR>&nbsp;&nbsp;&nbsp;IWorker* pIWorker =3D=20
            =
reinterpret_cast&lt;IWorker*&gt;(pN1);<BR>&nbsp;&nbsp;&nbsp;IJobDesc*=20
            pIJob=3D=20
            =
reinterpret_cast&lt;IJobDesc*&gt;(pN2);<BR>&nbsp;&nbsp;&nbsp;pIWorker-&gt=
;ProcessJob(pIJob);<BR>&nbsp;&nbsp;&nbsp;pServer-&gt;ChangeStatus(threadI=
d,=20
            false);<BR>&nbsp;&nbsp;}<BR>&nbsp;}<BR>&nbsp;return =
0;<BR>}</P>
            <P>void CThreadPoolImp::ChangeStatus(DWORD threadId, bool=20
            status)<BR>{<BR>&nbsp;CAutoLock CAutoLock(m_arrayCs);</P>
            <P>&nbsp;//retrieve the current thread=20
            handle<BR>&nbsp;Iterator_ThreadInfoMap =
i;<BR>&nbsp;ThreadInfo=20
            =
info;<BR>&nbsp;i=3Dm_threadMap.find(threadId);<BR>&nbsp;info=3Di-&gt;seco=
nd;<BR>//&nbsp;m_threadMap.Lookup(threadId,=20
            =
info);<BR>&nbsp;info.m_bBusyWorking=3Dstatus;<BR>&nbsp;m_threadMap.insert=
(m_threadMap.end(),ThreadInfoMap::value_type(threadId,=20
            info));<BR>}</P>
            <P>void CThreadPoolImp::ProcessJob(IJobDesc* pJob, IWorker* =
pWorker)=20
            =
const<BR>{<BR>&nbsp;::PostQueuedCompletionStatus(m_hWorkerIoPort,=20
            \<BR>&nbsp;&nbsp;reinterpret_cast&lt;DWORD&gt;(pWorker),=20
            =
\<BR>&nbsp;&nbsp;reinterpret_cast&lt;DWORD&gt;(pJob),\<BR>&nbsp;&nbsp;NUL=
L);<BR>}</P>
            <P>void =
CThreadPoolImp::AddThreads()<BR>{<BR>&nbsp;HANDLE&nbsp;=20
            hThread;<BR>&nbsp;DWORD&nbsp;nThreadId;<BR>&nbsp;unsigned =
int=20
            nCount=3Dm_threadMap.size();<BR>&nbsp;unsigned int=20
            nTotal=3Dmin(nCount+2, =
m_nNumberOfTotalThreads);<BR>&nbsp;for(unsigned=20
            int i=3D0; i&lt;nTotal-nCount; =
i++)<BR>&nbsp;{<BR>&nbsp;&nbsp;hThread=20
            =3D =
CreateThread(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NULL,=20

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -