如何在地图条目上锁定互斥锁和信号条件变量?

时间:2013-09-01 21:08:46

标签: c++ linux multithreading qt pthreads

我的Qt应用程序中有RAM存储库:

struct mutexData{
    pthread_mutex_t* mutex;
    pthread_cond_t* condition;
};

/**
 * in memory database implementation shared pointers to records are kept on the 
 * free store as this is the way std::vector allocates its elements
 * records itself are also on heap because this is the way we allocate them
 * in PosixClient callbacks
 */
class Repository {
public:
    typedef boost::shared_ptr<pthread_mutex_t> mutex_ptr;
    typedef boost::shared_ptr<pthread_cond_t> cond_ptr;

    typedef std::map<const IBAdditions::ContractEvent, 
                        std::vector<IBAdditions::rec_ptr> > ContractEventDataMap;
    typedef std::map<const IBAdditions::ContractEvent, mutexData> 
                                           ContractEventMutexMap;

    Repository(const std::vector<IBAdditions::ContractEvent>& contractEventVector);
    Repository();
    virtual ~Repository();

    /**
     * insert record into repository
     * @param ce key to the map, IB::Contract and IBAdditions::Event
     * @param rptr record to be stored into repository
     */
    void putRecord(const IBAdditions::ContractEvent ce, 
                   const IBAdditions::rec_ptr rptr);

    /**
     * get a reference to corresponding vector based on ContactEvent key
     * @param contractEvent
     * @return reference to vector of records
     */
    std::vector<IBAdditions::rec_ptr>& operator[](const 
                  IBAdditions::ContractEvent& contractEvent){
        return contractEventDataMap_[contractEvent];
    }

private:
    Repository(const Repository& orig);
    ContractEventDataMap contractEventDataMap_;
    ContractEventMutexMap contractEventMutexMap_;
};

现在,我有一个主线程,它将不断地将记录放入ContractEvents(key)的存储库向量中。当出现给定ContractEvent的新记录时,我希望特定的GUI对象基于来自存储库向量的数据来计算某些内容。因此,此类对象需要访问多个repo条目。我想到这样的设计,对象有posix线程等待条件变量,当每个传入的记录然后被放入repo时,Repository::putRecord函数将唤醒等待这个条件变量的休眠线程(在这个向量上)。这是一个很好的设计吗?其次,如何添加互斥量?在完整回购的每个载体或一个互斥体上?我是否需要在完整地图或每个条目上保护访问权限?一个线程可以同时使用vector1,vector2数据和其他使用vector3和vector4数据吗?或者这是一个并发访问(实际上是相同的地图)?

我希望每个对象在其感兴趣的向量中有新记录时开始自己的计算。我将举例说明8个对象,每个对象需要访问2个或更多向量,有些可能重叠,所以我认为每个向量都必须加以保护。我希望每个对象都能独立完成并行化。如果两个对象试图访问相同的向量怎么办?

目前我想到这样的事情:

/**
 * 
 * @param ce key to the map, IB::Contract and IBAdditions::Event
 * @param rptr record to be stored into repository
 * TODO: lock mutex here before push_back into Repository
 * and wake up waiting threads
 */
void Repository::putRecord(const IBAdditions::ContractEvent ce, 
                             const IBAdditions::rec_ptr rptr) {
    if(contractEventDataMap_.find(ce) == contractEventDataMap_.end()){
        /* 
         * there is no such ContractEvent in the map
         * next available mutex's identifier is contractEventDataMap_.size()
         * ( before inserting ce into contractEventDataMap_ )
         */
        printf("[Repository:putRecord] locking mutex %d\n",
                                              contractEventDataMap_.size());
        mutexData m;
        m.mutex = &repoMutexes[contractEventDataMap_.size()];
        m.condition = &repoConditions[contractEventDataMap_.size()];
        contractEventMutexMap_[ce] = m;

        contractEventDataMap_[ce] = std::vector<IBAdditions::rec_ptr>();
    }
    printf("[Repository] vector size is;%d\n", contractEventDataMap_[ce].size());
    contractEventDataMap_[ce].push_back(rptr);
    printf("[Repository] vector size is;%d\n", contractEventDataMap_[ce].size());
} 

0 个答案:

没有答案