如何在std :: deque中避免`deque iterator not dereferencable`?锁?

Raj*_*war 2 c++ mutex iterator deque

目前在我的项目中我有两个静态方法PushObjectsProcessObject.该PushObject方法将数据推送到静态双端队列,这个方法可以被多个线程访问,但是ProcessObject它总是由单个线程使用,用于从顶部检索对象并删除它们.现在我的问题是无论我尝试什么我总是最终(迟早会得到一个deque iterator not dereferencable错误.关于我能做些什么来阻止这个问题的任何建议.我的摘要PushObjectsProcessObject下面给出的

    void foo::PushObjects(obj A)
    {
        try
        {
            {//Begin Lock
                boost::lock_guard<boost::mutex> lock(mutex_push);
                mydeque.push_back(A);
            }//End Lock
            condition_read.notify_one(); //Inform the reader that it could start reading 
        }
        catch (std::exception& e)
        {
            __debugbreak();
        }
    }


    This is the static Reader method

    void foo::ProcessObject()
    {
        {//Begin Lock
            boost::unique_lock<boost::mutex> lock(mutex_process);
            while(true)
            {
                    while(mydeque.empty()) { condition_read.wait(lock); }
                    try
                    {
                        if(!mydeque.empty())
                        {
                                obj a = mydeque.front();
                                ......Process the object........
                                mydeque.pop_front();
                        }

                    }
                    catch (std::exception& e)
                    {
                        __debugbreak();
                    }
            }//end while
        }//End lock
    }
Run Code Online (Sandbox Code Playgroud)

从我所读到的是,一旦在双端队列中添加或删除项目,迭代器就会变为无效.有没有办法解决这个问题.

Dav*_*vid 5

看起来你没有使用相同的互斥(mutex_pushvs mutex_process)来读取和写入deque.你需要.写入内存并在不同线程上同时读取内存是不安全的.

其他说明:

obj a = mydeque.front();
......Process the object........
mydeque.pop_front();
Run Code Online (Sandbox Code Playgroud)

如果你管理你的锁具有最小的锁定时间可能会好得多...

obj a = std::move(mydeque.front());
mydeque.pop_front();
lock.unlock();
// process the object
lock.lock();
Run Code Online (Sandbox Code Playgroud)

您可能不需要锁定(或至少不需要相同的锁)来处理对象.通过这种方式,您的编写者仍然可以在处理时写入双端队列.另外需要注意的是,没有什么可以阻止你成为多生产者多消费者,而不仅仅是多生产者单一消费者.