c++ - 在容器中使用时断言在 boost::intrusive_ptr 中触发

标签 c++ linux boost

我有一个生产者-消费者安排来处理来自网络的事件。 Dispatcher 通过工作线程拥有的互斥锁保护队列为多个 EventHandler 线程提供工作。放入队列的事件对象使用boost::intrusive_ptr

class Event { ... }
typedef boost::intrusive_ptr<Event> EventPtr;

队列是一个模板,定义为:

template<typename Data>
class ConcurrentQueue : boost::noncopyable
{
protected:
    std::queue<Data> _queue;
    boost::mutex _dataMutex;
    boost::condition_variable _dataAvailable;
    ...
public:
    ...
    void push(Data const& data)
    {
        boost::mutex::scoped_lock lock(_dataMutex);
        _queue.push(data);
        lock.unlock();
        _dataAvailable.notify_one();
    }
...
};
...
typedef ConcurrentQueue<EventPtr> EventQueue;

EventHandler 等待事件放入其队列,并在可用时使用方法 waitAndPop 将其从队列中删除:

void waitAndPop(Data& poppedValue)
{
    boost::mutex::scoped_lock lock(_dataMutex);
    while(_queue.empty())
    {
        _dataAvailable.wait(lock);
    }
    poppedValue = _queue.front();
    _queue.pop();
}

这运行良好,但我随后需要确保 Dispatcher 将相关工作交给同一个 EventHandler。因此,我实现了一个 waitAndPeek 方法,将 Event 对象留在队列中,但返回指向它的指针。

void waitAndPeek(Data& peekedValue)
{
    boost::mutex::scoped_lock lock(_dataMutex);
    while(_queue.empty())
    {
        _dataAvailable.wait(lock);
    }
    peekedValue = _queue.front();
}

一旦事件处理完成,事件就会从队列中弹出。将事件留在队列中允许 Disptacher 检查队列头部的项目,看它是否与它试图分配的项目相关。 (以互斥保护的方式完成但未显示)

下面是从 EventQueue 中提取指针的代码:

EventPtr event;
// Loop, processing events placed on the queue.   
while (true)
{
    // Blocking call. Will halt the thread until there is work to do.
    _eventQueue->waitAndPeek(event);
    // Try to access event but ASSERT fires
    int id = event->getId();
    ...
}

问题是当我使用窥视指针时,intrusive_ptr 代码中触发了一个 ASSERT。

/usr/local/packages/Boost/1.40.0/include/boost/smart_ptr/intrusive_ptr.hpp:166:
T* boost::intrusive_ptr<T>::operator->() const [with T = Event]:
Assertion `px != 0' failed.

一旦我恢复代码以使用 waitAndPop 方法,问题就消失了,是什么导致 ASSERT 仅仅因为我将事件留在队列中而触发?

最佳答案

查看 intrusive_ptr 文档:

http://www.boost.org/doc/libs/1_46_1/libs/smart_ptr/intrusive_ptr.html#indirection

为了取消引用它,它必须持有一个非 NULL 指针。

关于c++ - 在容器中使用时断言在 boost::intrusive_ptr 中触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5512024/

相关文章:

C++数组输出地址?

Python(名称 "command"未定义)

android - 在 ubuntu 机器上为 nativescript 配置 android sdk 的问题

c++ - 使用 shared_ptrs 的 pair<unsigned int, boost::any> 类型的通用容器的线程安全实现

c++ - std::function、std::bind 和 std::ref 的 Clang 错误?

c++ - 为什么必须将函数必须返回的数组声明为静态数组?

c++ - 更好地处理 boost::program_options 中丢失/错误的键

c++ - 使用 boost json 读取 json 消息

c++ - 在 C/C++ 中将 int* 转换为 int(*)[n]

php - .htaccess 在 linux 服务器上不工作