2

我的 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(键)的存储库向量中。当出现给定 ContractEvent 的新记录时,我希望特定的 GUI 对象根据存储库向量中的数据进行计算。所以这样的对象需要访问多个 repo 条目。我考虑这样的设计,对象有 posix 线程等待条件变量,然后每个传入的记录将被放入 repo,Repository::putRecord函数将唤醒等待此条件变量(在此向量上)的睡眠线程。这是一个好的设计吗?其次,应该如何添加互斥锁?在完整 Repo 上的每个向量或一个互斥锁上?我是否需要在完整地图或每个条目上保护访问?一个线程可以同时使用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());
} 
4

0 回答 0