2012-01-17 3 views
1

私はキューからプッシュおよびペンディングに使用される次のコードを持っています。呼び出し元コードには複数のMsgQオブジェクトがあります。プッシュ機能とペンディング機能が_notFull->wait()_notEmpty->wait()条件付き待機で待機している可能性があります。これらの待機は_mutミューテックスによって保護されています。 notFull待機とnotEmpty待機は、emptyfull変数で動作します。ACE_Condition Waitで保持されているmutexを取得できません。

デストラクタが呼び出されると、_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

OSの独自のセマフォーのものを実装し、動作するかどうかを確認するだけです。もしそうなら、あなたはACEの実装をうかがい、問題を見ることができます。いずれにしても、より多くの洞察力が得られます。私は、このタイプのものにACE抽象化を使用することは、その価値よりも問題があることを発見しました。 – EdH

答えて

0

あり、私はそれを作り直し示唆しているように、コードには多くの問題のように見える:

  1. あなたが_mutを取得しているので、あなたが両方Postで待機状態に入る前に、デッドロックの可能性を持っていますおよびPend機能。代わりに、私はacquireミューテックスを作成することができますACE_Guardクラスを使用して見て示唆し、破壊されたときにそれを解放するACE_Mutexacquirereleaseを使用しての
  2. 自分で作成する代わりにACE_Message_Queueを使用してみませんか?
関連する問題