RT,代码和问题描述如下,请多指教:struct stMsg;
class MsgList
{
public:
void push_back(stMsg *pMsg);
bool pop_front(stMsg msg);
bool Empty();
//...
};
MsgList g_MsgList;struct THREAD_INFO
{
DWORD m_ThreadID;
HANDLE m_ThreadHandle;
HANDLE m_ExitHandle;
HANDLE m_SemaphoreHandle;
};DWORD WINAPI ThreadFatherPro(void *lp)
{
//...
THREAD_INFO *pInfo = new THREAD_INFO;
pInfo->m_ExitHandle = CreateEvent( NULL, FALSE, FALSE, NULL ); //初始计数为0,总计数为1
pInfo->m_SemaphoreHandle = CreateSemaphore(NULL, 0, 1, NULL); //----------------语句(1) pInfo->m_ThreadHandle = CreateThread(0,0,ThreadMsgPro,pInfo,0,&(pInfo->m_ThreadID));
//...
}DWORD WINAPI ThreadMsgPro(void *lp)
{
THREAD_INFO *pInfo = (THREAD_INFO *)lp;
HANDLE handleBuf[2];
handleBuf[1] = pInfo->m_ExitHandle;
handleBuf[2] = pInfo->m_SemaphoreHandle;
while(true)
{
long rt = WaitForMultipleObjects(2, handleBuf, false, 200); //----------------语句(2)
if ((rt - WAIT_OBJECT_0) == 1)
{
if (rt != WAIT_TIMEOUT) //如果不是超时,则说明消息队列不为空
{
g_MsgList.pop_front(msg);
//... if (!g_MsgList.Empty())//消息队列不为空,则恢复本次计数,以便下次循环可以继续
{
ReleaseSemaphore(pInfo->m_SemaphoreHandle, 1, NULL); //----------------语句(3)
}
}
}
else if (rt == WAIT_OBJECT_0)
{
break; //退出线程标识
}
else
{
//...
}
} SetEvent( pInfo->m_ThreadHandle );//通知副线程已经退出 return 0;
}DWORD WINAPI ThreadNetPro(void *lp)
{
//...
stMsg msg;
Receive(msg); //收到消息
g_MsgList.push_back(&msg); //收到消息,释放一个信号计数
ReleaseSemaphore(pInfo->m_SemaphoreHandle, 1, NULL); //----------------语句(4)
//...
}简要说明:
1、父线程ThreadFatherPro创建了两个线程:消息处理线程ThreadMsgPro、网络线程ThreadNetPro;
2、网络线程ThreadNetPro收到消息会放到公共消息队列里g_MsgList;
3、消息处理线程ThreadMsgPro从g_MsgList取出消息做逻辑处理;
4、网络消息可能隔一定时间间隔才会收到,也可能连续收到很多条消息;思路:
使用信号量通知的方式。
1、当g_MsgList中有消息到来,立即通知消息处理线程ThreadMsgPro处理;
2、当g_MsgList为空时,暂时挂起ThreadMsgPro,以降低资源消耗;做法:
1、在创建2个子线程前,在父线程中创建一个 “初始计数为0,总计数为1”的信号量,即 语句(1)
2、网络线程ThreadMsgPro通过WaitForMultipleObjects函数处理,当冲信号量获取到使用权,则取出一条消息处理;
消息处理完后,再判断g_MsgList是否为空,如果为空,则不恢复信号量计数,
如果不为空,则如 语句(3) 使用ReleaseSemaphore为信号量恢复一个计数,以便下次循环继续取出消息处理(因为
信号总使用计数为1,本次已经使用了一个信号量,如过不释放的话,并且网络上也没有收到消息,那么剩余的消息就
会由于拿不到使用权而等待)
3、网络线程ThreadNetPro收到消息后,把消息放到公共消息队列,同时如 语句(4) 使用ReleaseSemaphore函数释放
一个计数,以保证线程ThreadMsgPro能够立即受信,从而处理网络消息。
问题:
1、网络线程ThreadNetPro在收到网络消息后,立即使用 语句(4),
可能会有这样一个问题,在执行语句(4)的时候,信号两的使用计数可能为1,此时已经达到最大使用计数,
如果此时再使用函数ReleaseSemaphore释放一个计数,这样会不会有问题?2、如果问题1所描述的问题不存在,那么该方案是否具有可行性,3、如果该方案可行,是否还有其他可以改进的地方。还是新手,请各位大侠不吝赐教,感激不尽。
class MsgList
{
public:
void push_back(stMsg *pMsg);
bool pop_front(stMsg msg);
bool Empty();
//...
};
MsgList g_MsgList;struct THREAD_INFO
{
DWORD m_ThreadID;
HANDLE m_ThreadHandle;
HANDLE m_ExitHandle;
HANDLE m_SemaphoreHandle;
};DWORD WINAPI ThreadFatherPro(void *lp)
{
//...
THREAD_INFO *pInfo = new THREAD_INFO;
pInfo->m_ExitHandle = CreateEvent( NULL, FALSE, FALSE, NULL ); //初始计数为0,总计数为1
pInfo->m_SemaphoreHandle = CreateSemaphore(NULL, 0, 1, NULL); //----------------语句(1) pInfo->m_ThreadHandle = CreateThread(0,0,ThreadMsgPro,pInfo,0,&(pInfo->m_ThreadID));
//...
}DWORD WINAPI ThreadMsgPro(void *lp)
{
THREAD_INFO *pInfo = (THREAD_INFO *)lp;
HANDLE handleBuf[2];
handleBuf[1] = pInfo->m_ExitHandle;
handleBuf[2] = pInfo->m_SemaphoreHandle;
while(true)
{
long rt = WaitForMultipleObjects(2, handleBuf, false, 200); //----------------语句(2)
if ((rt - WAIT_OBJECT_0) == 1)
{
if (rt != WAIT_TIMEOUT) //如果不是超时,则说明消息队列不为空
{
g_MsgList.pop_front(msg);
//... if (!g_MsgList.Empty())//消息队列不为空,则恢复本次计数,以便下次循环可以继续
{
ReleaseSemaphore(pInfo->m_SemaphoreHandle, 1, NULL); //----------------语句(3)
}
}
}
else if (rt == WAIT_OBJECT_0)
{
break; //退出线程标识
}
else
{
//...
}
} SetEvent( pInfo->m_ThreadHandle );//通知副线程已经退出 return 0;
}DWORD WINAPI ThreadNetPro(void *lp)
{
//...
stMsg msg;
Receive(msg); //收到消息
g_MsgList.push_back(&msg); //收到消息,释放一个信号计数
ReleaseSemaphore(pInfo->m_SemaphoreHandle, 1, NULL); //----------------语句(4)
//...
}简要说明:
1、父线程ThreadFatherPro创建了两个线程:消息处理线程ThreadMsgPro、网络线程ThreadNetPro;
2、网络线程ThreadNetPro收到消息会放到公共消息队列里g_MsgList;
3、消息处理线程ThreadMsgPro从g_MsgList取出消息做逻辑处理;
4、网络消息可能隔一定时间间隔才会收到,也可能连续收到很多条消息;思路:
使用信号量通知的方式。
1、当g_MsgList中有消息到来,立即通知消息处理线程ThreadMsgPro处理;
2、当g_MsgList为空时,暂时挂起ThreadMsgPro,以降低资源消耗;做法:
1、在创建2个子线程前,在父线程中创建一个 “初始计数为0,总计数为1”的信号量,即 语句(1)
2、网络线程ThreadMsgPro通过WaitForMultipleObjects函数处理,当冲信号量获取到使用权,则取出一条消息处理;
消息处理完后,再判断g_MsgList是否为空,如果为空,则不恢复信号量计数,
如果不为空,则如 语句(3) 使用ReleaseSemaphore为信号量恢复一个计数,以便下次循环继续取出消息处理(因为
信号总使用计数为1,本次已经使用了一个信号量,如过不释放的话,并且网络上也没有收到消息,那么剩余的消息就
会由于拿不到使用权而等待)
3、网络线程ThreadNetPro收到消息后,把消息放到公共消息队列,同时如 语句(4) 使用ReleaseSemaphore函数释放
一个计数,以保证线程ThreadMsgPro能够立即受信,从而处理网络消息。
问题:
1、网络线程ThreadNetPro在收到网络消息后,立即使用 语句(4),
可能会有这样一个问题,在执行语句(4)的时候,信号两的使用计数可能为1,此时已经达到最大使用计数,
如果此时再使用函数ReleaseSemaphore释放一个计数,这样会不会有问题?2、如果问题1所描述的问题不存在,那么该方案是否具有可行性,3、如果该方案可行,是否还有其他可以改进的地方。还是新手,请各位大侠不吝赐教,感激不尽。
解决方案 »
- 获取CPU 序列号问题
- 动态创建 CWinApp* pApp 实例问题。
- 求CPropertyPage Class E 文翻译(2)
- 调查:大家用Visual C++做开发,操作系统是哪个?
- 为何无法获得文本框的内容?
- DLL 的共享数据段中能否放一个 Event 句柄,进程A使用 SetEvent(handle),进程B WaitForSingleObject ???
- 出学者问,高分求解,有关CDHtmlDialog的问题
- 关于CreateMutex函数
- 想做一个类似outlook的界面...
- 关于内存中画图?sos!
- mfc tab控件问题求助
- 请问如何在调用局域网其他机器上的数据库时,输入共享账户密码
请各位大侠关注下其他问题,麻烦帮忙看看
http://download.csdn.net/source/845221