线程池的整个代码过程整理:
先整理不排队的消息的处理过程:
1.在单例模式类里的CMessageProcesser构造函数里进行 new 多个的thread对象,然后存储在一个vector容器里
for (int i = 0; i < _minthread; i++)
{
Thread* pthread = new Thread;
if (NULL != pthread)
{
_threads.push_back(pthread);
}
}
2.然后平台会调用CMessageProcesser::start函数,函数完成如下功能:
完成了两件事:
(1)_bstart = true;
(2)遍历在构造函数中的容器,调用每个的start函数然后,开始创建线程,然后执行到每个的run函数。
for (int i = 0; i < _threads.size(); i++)
{
if (NULL != _threads[i])
{
try
{
_threads[i]->start(this);
}
catch(...)
{
}
}
}
3.CMessageProcesser::run函数,函数完成如下功能:(run函数是死循环)
(1)定义了一个变量,然后对变量进行赋值
SegMsg msg ={0}; Segbase Msg的一个结构体。初值全部为0.
然后这个类CMessageProcesser定义的时候,有个MsgQueue _msgque; //message queue.
类对象,
这个类对象的成员变量又有个 std::queue<SegMsg> _msgque;
有点重名了,但是无所谓:
对于这个最近的这个 std::queue<SegMsg> _msgque又有两个方法对它进行操作,
一个是virtual sg_int32_t PushMessage(SegMsg& msg)
一个是virtual SegMsg GetMessage(int ntimeout = 0xFFFFFF)
(2)获取队列中要处理的消息,如果没有获取到,或者是 _bstart=false就不处理了。
if (msg._msg == MSG_QUITTHREAD || !_bstart)
{
//OutputDebugString(_T("pool thread quit\n"));
break;
}
(3)如果获取到了消息,就把要处理的线程数加1
InterlockedIncrement(&_busythreadcount);
(4)把调用pushmessage消息的函数指针,拿出来,一会就调用它的 OnThreadMessage
IMessage* pmodule = (IMessage*)msg._ltarget;
if (msg._ltarget != NULL)
{
try
{
pmodule->OnThreadMessage(msg);
}
(5)把正在处理的线程数减1.
4.sg_int32_t CMessageProcesser::pushmessage(IMessage* pmodule, SegMsg msg)
这个方法是网关调用的,比方说是短信插件,调用的这个,然后会把 this指针,和自己建立的 SegMsg变量传进来。
(1)msg._ltarget = (sg_uint32_t)pmodule; 把this指针转化为整数,然后赋给传进来的 msg._ltarget
(2)_msgque.PushMessage(msg);
把它放入队列里,一会run函数会从队列里把数据取出来。
这样的话整个线程就返回了,上面的处理流程针对的是这个不需要排队的线程。如果是需要排队的线程,那么还会比这个更加的复杂一些。
下面来说下需要排队的线程的处理方式:
对于排队的消息处理方式有两处有些不同,
1.sg_int32_t CMessageProcesser::pushmessage(IMessage* pmodule, SegMsg msg)的时候,有些不同,没有和不排队的消息放在一起进行处理
if(msg._lNeedqueue)
{
nRet =AddQueueMsg(msg._ltarget,msg);
}
(1)
先整理不排队的消息的处理过程:
1.在单例模式类里的CMessageProcesser构造函数里进行 new 多个的thread对象,然后存储在一个vector容器里
for (int i = 0; i < _minthread; i++)
{
Thread* pthread = new Thread;
if (NULL != pthread)
{
_threads.push_back(pthread);
}
}
2.然后平台会调用CMessageProcesser::start函数,函数完成如下功能:
完成了两件事:
(1)_bstart = true;
(2)遍历在构造函数中的容器,调用每个的start函数然后,开始创建线程,然后执行到每个的run函数。
for (int i = 0; i < _threads.size(); i++)
{
if (NULL != _threads[i])
{
try
{
_threads[i]->start(this);
}
catch(...)
{
}
}
}
3.CMessageProcesser::run函数,函数完成如下功能:(run函数是死循环)
(1)定义了一个变量,然后对变量进行赋值
SegMsg msg ={0}; Segbase Msg的一个结构体。初值全部为0.
然后这个类CMessageProcesser定义的时候,有个MsgQueue _msgque; //message queue.
类对象,
这个类对象的成员变量又有个 std::queue<SegMsg> _msgque;
有点重名了,但是无所谓:
对于这个最近的这个 std::queue<SegMsg> _msgque又有两个方法对它进行操作,
一个是virtual sg_int32_t PushMessage(SegMsg& msg)
一个是virtual SegMsg GetMessage(int ntimeout = 0xFFFFFF)
(2)获取队列中要处理的消息,如果没有获取到,或者是 _bstart=false就不处理了。
if (msg._msg == MSG_QUITTHREAD || !_bstart)
{
//OutputDebugString(_T("pool thread quit\n"));
break;
}
(3)如果获取到了消息,就把要处理的线程数加1
InterlockedIncrement(&_busythreadcount);
(4)把调用pushmessage消息的函数指针,拿出来,一会就调用它的 OnThreadMessage
IMessage* pmodule = (IMessage*)msg._ltarget;
if (msg._ltarget != NULL)
{
try
{
pmodule->OnThreadMessage(msg);
}
(5)把正在处理的线程数减1.
4.sg_int32_t CMessageProcesser::pushmessage(IMessage* pmodule, SegMsg msg)
这个方法是网关调用的,比方说是短信插件,调用的这个,然后会把 this指针,和自己建立的 SegMsg变量传进来。
(1)msg._ltarget = (sg_uint32_t)pmodule; 把this指针转化为整数,然后赋给传进来的 msg._ltarget
(2)_msgque.PushMessage(msg);
把它放入队列里,一会run函数会从队列里把数据取出来。
这样的话整个线程就返回了,上面的处理流程针对的是这个不需要排队的线程。如果是需要排队的线程,那么还会比这个更加的复杂一些。
下面来说下需要排队的线程的处理方式:
对于排队的消息处理方式有两处有些不同,
1.sg_int32_t CMessageProcesser::pushmessage(IMessage* pmodule, SegMsg msg)的时候,有些不同,没有和不排队的消息放在一起进行处理
if(msg._lNeedqueue)
{
nRet =AddQueueMsg(msg._ltarget,msg);
}
(1)