2012-01-17 56 views
1

我有以下用于从队列中推送和挂起的代码。调用者代码具有多个MsgQ对象。 Push和Pend函数有可能等待_notFull->wait()_notEmpty->wait()条件等待。这些等待由_mut互斥锁保护。 notFull和notEmpty等待在emptyfull变量上运行。无法获取由ACE_Condition持有的互斥等待

当析构函数被调用时,_deleteQueue被内部调用,我想通过这个函数向正在等待的线程发送信号以清除并停止等待信号到来。一旦完成,我删除我的对象。但是,在_deleteQueue函数中,当我尝试执行_mut->acquire()时,我无法获取互斥锁。即使我忽略获得,我无法broadcast这些等待线程。我哪里错了?

谢谢, Vikram。

MsgQ::~MsgQ() 
{ 
    _deleteQueue(); 

    delete _mut;_mut=NULL; 
    delete _notFull;_notFull=NULL; 
    delete _notEmpty;_notEmpty=NULL; 
    delete _PostMutex; _PostMutex = NULL; 
    delete _PendMutex; _PendMutex = NULL; 
    delete _PostInProgressMutex; _PostInProgressMutex = NULL; 
    delete _PendInProgressMutex; _PendInProgressMutex = NULL; 
    delete _DisconnectMutex; _DisconnectMutex = NULL; 
    free(_ptrQueue); _ptrQueue = NULL; 
} 

int MsgQ::Post(Message* msg) 
{ 
    _PostMutex->acquire(); 
    _postInProgress++; 
    _PostMutex->release(); 

    if (msg) 
    msg->print(); 

    _mut->acquire(); 
    while (full) 
    { 
    _notFull->wait(); 
    } 

    if (!_disconnectInProgress) 
    _queuePush(msg); 
    _mut->release(); 

    _PostMutex->acquire(); 
    _postInProgress--; 
    if (_postInProgress==0) 
    { 
    _PostInProgressMutex->signal(); 
    } 
    _PostMutex->release(); 

    return _notEmpty->signal(); 
} 

int MsgQ::Pend(Message*& msg) 
{ 

    _PendMutex->acquire(); 
    _pendInProgress++; 
    _PendMutex->release(); 

    _mut->acquire(); 
    while (empty) 
    _notEmpty->wait(); 

    if (!_disconnectInProgress) 
    { 
    _queuePop(msg); 
    } 
    _mut->release(); 

    _PendMutex->acquire(); 
    _pendInProgress--; 
    if (_pendInProgress == 0) 
    { 
    _PendInProgressMutex->signal(); 
    } 
    _PendMutex->release(); 

    return _notFull->signal(); 
} 

void MsgQ::_deleteQueue() 
{ 
    _PostMutex->acquire(); 
    if (_postInProgress != 0) 
    { 
    _PostMutex->release(); 
    TRACE("Acquiring Mutex."); 
    _mut->acquire(); 
    full = 0; 
    _notFull->broadcast(); 
    _mut->release(); 
    _PostInProgressMutex->wait(); 
    } 
    else 
    { 
    _PostMutex->release(); 
    } 

    _PendMutex->acquire(); 
    if (_pendInProgress != 0) 
    { 
    _PendMutex->release(); 
    TRACE("Acquiring Mutex."); 
    _mut->acquire(); 
    empty = 0; 
    _notEmpty->broadcast(); 
    _mut->release(); 
    _PendInProgressMutex->wait(); 
    } 
    else 
    { 
    _PendMutex->release(); 
    } 
} 

void MsgQ::_initQueue() 
{ 
    _ptrQueue = (Message **)(malloc (size * sizeof (Message*))); 

    if (_ptrQueue == NULL) 
    { 
    cout << "queue could not be created!" << endl; 
    } 
    else 
    { 
    for (int i = 0; i < size; i++) 
     *(_ptrQueue + i) = NULL; 
    empty = 1; 
    full = 0; 
    head = 0; 
    tail = 0; 

     try{ 
     _mut = new ACE_Mutex() ; 
     _notFull = new ACE_Condition<ACE_Mutex>(*_mut); 
     _notEmpty = new ACE_Condition<ACE_Mutex>(*_mut); 

    _PostMutex = new ACE_Mutex(); 
    _PendMutex = new ACE_Mutex(); 
    _PostInProgressMutex = new ACE_Condition<ACE_Mutex>(*_PostMutex); 
    _PendInProgressMutex = new ACE_Condition<ACE_Mutex>(*_PendMutex); 
    _DisconnectMutex = new ACE_Mutex(); 

    _postInProgress = 0; 
    _pendInProgress = 0; 
    _disconnectInProgress = false; 

     }catch(...){ 
      cout << "you should not be here" << endl; 
     } 
    } 
} 
+0

只是实现它与您的操作系统自己的信号量的东西,看看它是否工作。如果确实如此,那么您可以在ACE的实施中徘徊 - 并查看问题。无论哪种方式,你将有更多的见解。我发现使用ACE抽象这种类型的东西比它的价值更麻烦。 – EdH 2012-01-22 23:50:43

回答

0

似乎有很多问题的代码,所以我会建议重做吧:

  1. 您有死锁的潜力,因为你正在获得_mut你进入等待状态在这两个Post前和Pend函数。
  2. 而不是使用acquirereleaseACE_Mutex我建议考虑使用它可以创建时acquire互斥ACE_Guard类,并毁坏了,当其释放。
  3. 为什么不使用ACE_Message_Queue而不是自己创建?