最近解決了以前遺留的ACE問題(原來的應(yīng)用退出時實際上各子線程不是自然退出,而是因為進(jìn)程終止而強(qiáng)制退出的),高興!特此記錄一下。
我們的應(yīng)用使用反應(yīng)器框架模式,反應(yīng)器框架通過任務(wù)的消息隊列和具體處理任務(wù)解耦,考試,大提示任務(wù)(繼承自ACE_Task)線程通過getq獲取消息內(nèi)容并處理。
原來的程序類似于下面:
int My_Task::open(void* args)
{
activate(THR_NEW_LWP | THR_JOINABLE, 5, 1);//打開5個工作者線程
return 0;
}
int My_Task::svc()
{
while ( 0==m_nEnd ) //m_nEnd結(jié)束標(biāo)記,為1時退出線程
{
ACE_Message_Block *mb =0;
try{
getq(mb);
...
}
}
}
實際上即使有設(shè)置結(jié)束標(biāo)記,上面的辦法也不能自然退出,因為并不是每個任務(wù)工作者線程getq都有結(jié)果(有的處于饑餓狀態(tài),考試,大提示會一直阻塞在getq上,造成不能自然退出)。
可以這樣改下:
//任務(wù)有很多,所以寫成宏方便調(diào)用,主要是為getq設(shè)置1秒超時
#define MY_GETQ(X) \
ACE_Time_Value tvTmp = ACE_OS::gettimeofday ();\
tvTmp += ACE_Time_Value(1);\
getq(X, &tvTmp);\
if (X == NULL)\
continue;
...
int My_Task::svc()
{
while ( 0==m_nEnd ) //m_nEnd結(jié)束標(biāo)記
{
ACE_Message_Block *mb =0;
try{
MY_GETQ(mb);
...
}
}
}
再查看了一下ACE例程,發(fā)現(xiàn)有的用了超時的辦法,有的用這個來判斷是否退出:
virtual int svc (void)
{
while (1)
{
ACE_Message_Block *mb = NULL;
if (this->getq (mb) == -1)
{
ACE_DEBUG ((LM_INFO,
ACE_TEXT ("(%t) Shutting down\n")));
break;
}
// Process the message.
process_message (mb);
}
return 0;
}
不過就有一個問題,什么情況下getq會返回-1 ?
我們的應(yīng)用使用反應(yīng)器框架模式,反應(yīng)器框架通過任務(wù)的消息隊列和具體處理任務(wù)解耦,考試,大提示任務(wù)(繼承自ACE_Task)線程通過getq獲取消息內(nèi)容并處理。
原來的程序類似于下面:
int My_Task::open(void* args)
{
activate(THR_NEW_LWP | THR_JOINABLE, 5, 1);//打開5個工作者線程
return 0;
}
int My_Task::svc()
{
while ( 0==m_nEnd ) //m_nEnd結(jié)束標(biāo)記,為1時退出線程
{
ACE_Message_Block *mb =0;
try{
getq(mb);
...
}
}
}
實際上即使有設(shè)置結(jié)束標(biāo)記,上面的辦法也不能自然退出,因為并不是每個任務(wù)工作者線程getq都有結(jié)果(有的處于饑餓狀態(tài),考試,大提示會一直阻塞在getq上,造成不能自然退出)。
可以這樣改下:
//任務(wù)有很多,所以寫成宏方便調(diào)用,主要是為getq設(shè)置1秒超時
#define MY_GETQ(X) \
ACE_Time_Value tvTmp = ACE_OS::gettimeofday ();\
tvTmp += ACE_Time_Value(1);\
getq(X, &tvTmp);\
if (X == NULL)\
continue;
...
int My_Task::svc()
{
while ( 0==m_nEnd ) //m_nEnd結(jié)束標(biāo)記
{
ACE_Message_Block *mb =0;
try{
MY_GETQ(mb);
...
}
}
}
再查看了一下ACE例程,發(fā)現(xiàn)有的用了超時的辦法,有的用這個來判斷是否退出:
virtual int svc (void)
{
while (1)
{
ACE_Message_Block *mb = NULL;
if (this->getq (mb) == -1)
{
ACE_DEBUG ((LM_INFO,
ACE_TEXT ("(%t) Shutting down\n")));
break;
}
// Process the message.
process_message (mb);
}
return 0;
}
不過就有一個問題,什么情況下getq會返回-1 ?