我用dll编写了Visual c++ in Visual Studio 2008,供多个进程和线程使用。

该场景是这样的:

一个编写器进程调用dll的“init”方法,该方法创建共享内存,并在共享内存中创建boost multi_index容器,并通过调用其insert方法开始推送数据。

创建容器后,最多有10个阅读器应用程序通过调用search方法开始在其中执行搜索操作。

一段时间(例如30秒)之后,编写器进程将创建一个删除线程,该线程开始以每秒1次删除操作的频率删除容器中的数据(最旧的数据)。

代码的头文件(hpp)如下所示:

class SharedMemoryContainer
{

private:

    typedef boost::interprocess::allocator<SharedObj, managed_shared_memory::segment_manager> ShmemAllocator;

    typedef multi_index_container<
        SharedObj,
            indexed_by<
                random_access<>,
                ordered_non_unique< member<SharedObj, unsigned _int64, &SharedObj::id >
            >, ShmemAllocator
    > SharedMemoryContainerType;


    struct compare
    {
        unsigned _int64 _compare;
        int _trackNo;
        compare(unsigned _int64 id, int trackNo) : _compare(id), _trackNo(trackNo) {}
        bool operator()(SharedObj const& item) const {return (item.id == _compare && item.trackNo == _trackNo);};
    };


    static boost::mutex mutex_; // the mutex that i used to synchronize the operations

    /*
    .
    .
    some more variables and methods...
    .
    .
    */

public:

    bool insert (/*.. parameters ..*/);

    SharedObj search (/*.. parameters ..*/);

    bool delete ();

    /*
    .
    .
    some more variables and methods...
    .
    .
    */
};

在实现(cpp)文件中,我像这样使用互斥锁:
boost::mutex SharedMemoryContainer::mutex_; // for the static mutex

// insert new data to shared container
bool SharedMemoryContainer::insert(/*.. parameters ..*/)
{
    boost::mutex::scoped_lock m(mutex_);
    bool result;
        try
        {
            // Make the insertion here
        }
        catch(interprocess_exception &ex)
        {
            std::cout << "Error in Insert!" << std::endl <<ex.what() << std::endl;
            return false;
        }
    return result;
}

// reader applications perform search in shared container
SharedObj SharedMemoryContainer::search(/*.. parameters ..*/)
{
    boost::mutex::scoped_lock m(mutex_);

    IndexType& idIndex = myContainer->get<0>();
    IteratorType current = std::find_if(idIndex.begin(), idIndex.end(), compare(id, trackNo));
    /*
    .
    .
    other operations
    .
    .
    */
}

// it always delete the oldest one
bool SharedMemoryContainer::delete()
{
    boost::mutex::scoped_lock m(mutex_);

    IndexType& idIndex = myContainer->get<0>();
    it first = myContainer->begin();
    idIndex.erase(first);
}

这种互斥锁用法似乎不起作用。因为它总是在不同的时间崩溃(我是说它发生了变化,可能是40秒或5分钟后等等)。

由于删除线程更改了我猜想的容器,它与compare struct一起在"access violation unable to read location ..."(在搜索-find_if中被调用)中崩溃了(如果没有删除线程,它可以正常工作)

如何保持共享的multi_index容器线程/进程安全和同步?

谢谢...

编辑:

关于互斥的工作逻辑,我还有一个问题。

就我阅读互斥锁而言,它只是锁定代码以防止多次输入代码块,而不是容器本身。因此,例如,在上面的代码中,当阅读器应用程序进入“搜索”方法并锁定容器时,没有其他阅读器应用程序可以输入代码,但是删除线程也可以通过输入“删除”方法来完成其任务并更改容器?

那么如何一次防止对一个共享容器进行多次操作呢?

最佳答案

如果您使用read this link,则第一段说明:



这意味着每个使用您的DLL的进程都将拥有它自己的互斥体的单独且未共享的拷贝。因此,即使两个进程共享该容器,互斥体也将是独立的,并且不会共享,从而导致数据争用。

10-06 05:11
查看更多