【问题标题】:Unable to acquire a mutex held by a ACE_Condition wait无法获取 ACE_Condition 等待所持有的互斥锁
【发布时间】:2012-01-17 15:04:40
【问题描述】:

我有以下代码用于从队列中推送和挂起。调用方代码有多个 MsgQ 对象。 Push 和 Pend 函数可能正在等待 _notFull->wait()_notEmpty->wait() 条件等待。这些等待受 _mut 互斥体保护。 notFull 和 notEmpty 等待对 emptyfull 变量进行操作。

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

谢谢, 维克拉姆。

    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;
        }
    }
}

【问题讨论】:

  • 用你的操作系统自己的信号量实现它,看看它是否有效。如果是这样,您可以在 ACE 的实现中步履蹒跚——然后看看问题所在。无论哪种方式,你都会有更多的洞察力。我发现对这种类型的东西使用 ACE 抽象比它的价值更麻烦。

标签: ace


【解决方案1】:

代码似乎有很多问题,所以我建议重新编写它:

  1. 您有可能出现死锁,因为您在进入 PostPend 函数的等待条件之前获取了 _mut
  2. 我建议不要在ACE_Mutex 上使用acquirerelease,而是使用ACE_Guard 类,该类可以在创建时acquire 互斥锁,并在销毁时释放它。
  3. 为什么不使用ACE_Message_Queue 而不是自己创建?

【讨论】:

    猜你喜欢
    • 2012-06-13
    • 2010-12-07
    • 2015-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-12
    相关资源
    最近更新 更多