最近解決了以前遺留的ACE問(wèn)題(原來(lái)的應(yīng)用退出時(shí)實(shí)際上各子線程不是自然退出,而是因?yàn)檫M(jìn)程終止而強(qiáng)制退出的),高興!特此記錄一下。
我們的應(yīng)用使用反應(yīng)器框架模式,反應(yīng)器框架通過(guò)任務(wù)的消息隊(duì)列和具體處理任務(wù)解耦,考試,大提示任務(wù)(繼承自ACE_Task)線程通過(guò)getq獲取消息內(nèi)容并處理。
原來(lái)的程序類(lèi)似于下面:
int My_Task::open(void* args)
{
activate(THR_NEW_LWP | THR_JOINABLE, 5, 1);//打開(kāi)5個(gè)工作者線程
return 0;
}
int My_Task::svc()
{
while ( 0==m_nEnd ) //m_nEnd結(jié)束標(biāo)記,為1時(shí)退出線程
{
ACE_Message_Block *mb =0;
try{
getq(mb);
...
}
}
}
實(shí)際上即使有設(shè)置結(jié)束標(biāo)記,上面的辦法也不能自然退出,因?yàn)椴⒉皇敲總€(gè)任務(wù)工作者線程getq都有結(jié)果(有的處于饑餓狀態(tài),考試,大提示會(huì)一直阻塞在getq上,造成不能自然退出)。
可以這樣改下:
//任務(wù)有很多,所以寫(xiě)成宏方便調(diào)用,主要是為getq設(shè)置1秒超時(shí)
#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)有的用了超時(shí)的辦法,有的用這個(gè)來(lái)判斷是否退出:
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;
}
不過(guò)就有一個(gè)問(wèn)題,什么情況下getq會(huì)返回-1 ?
我們的應(yīng)用使用反應(yīng)器框架模式,反應(yīng)器框架通過(guò)任務(wù)的消息隊(duì)列和具體處理任務(wù)解耦,考試,大提示任務(wù)(繼承自ACE_Task)線程通過(guò)getq獲取消息內(nèi)容并處理。
原來(lái)的程序類(lèi)似于下面:
int My_Task::open(void* args)
{
activate(THR_NEW_LWP | THR_JOINABLE, 5, 1);//打開(kāi)5個(gè)工作者線程
return 0;
}
int My_Task::svc()
{
while ( 0==m_nEnd ) //m_nEnd結(jié)束標(biāo)記,為1時(shí)退出線程
{
ACE_Message_Block *mb =0;
try{
getq(mb);
...
}
}
}
實(shí)際上即使有設(shè)置結(jié)束標(biāo)記,上面的辦法也不能自然退出,因?yàn)椴⒉皇敲總€(gè)任務(wù)工作者線程getq都有結(jié)果(有的處于饑餓狀態(tài),考試,大提示會(huì)一直阻塞在getq上,造成不能自然退出)。
可以這樣改下:
//任務(wù)有很多,所以寫(xiě)成宏方便調(diào)用,主要是為getq設(shè)置1秒超時(shí)
#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)有的用了超時(shí)的辦法,有的用這個(gè)來(lái)判斷是否退出:
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;
}
不過(guò)就有一個(gè)問(wèn)題,什么情況下getq會(huì)返回-1 ?

