C++技巧(ACE_Task自然退出的問(wèn)題)

字號(hào):

最近解決了以前遺留的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 ?