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

字號:

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