Вы можете искать std::map
элементы либо через оператор индекса []
, либо используя метод find
.std::map
не вызывается, поэтому вы не можете использовать синтаксис ds_lock(rid,cid)
.
Ваша карта должна использовать std::pair< unsigned int, unsigned int >
в качестве типа ключа.
После этого вы сможете заблокироватьиспользование omp_set_lock(&ds_lock[std::make_pair(rid,cid)]);
Однако вам необходимо убедиться, что каждый использованный элемент карты был инициализирован заранее, в противном случае, поскольку std::map
не является потокобезопасным, вы столкнетесь с проблемами, когда оператор индекса автоматически создаст новыйэлементам, вам также нужно будет вызвать omp_init_lock
для вновь созданных значений.
Чтобы гарантировать, что omp_unset_lock
всегда вызывается с использованием шаблона RAII , будет целесообразно.Полностью работающий пример устранения вышеуказанных проблем может выглядеть примерно так:
class omp_locker
{
public:
omp_locker( omp_lock_t& lock )
: lock( lock )
{
omp_set_lock( &lock );
}
omp_locker( const omp_locker& ) = delete;
omp_locker& operator=( const omp_locker& ) = delete;
~omp_locker()
{
omp_unset_lock( &lock );
}
private:
omp_lock_t& lock;
};
std::map< std::pair< unsigned int, unsigned int >, omp_lock_t> ds_lock;
std::mutex ds_lock_mutex;
omp_lock_t& getLock( unsigned int rid, unsigned int cid )
{
std::lock_guard lock( ds_lock_mutex );
auto key = std::make_pair( rid, cid );
auto it = ds_lock.find( key );
if ( it == ds_lock.end() )
{
it = ds_lock.insert( it, std::make_pair( key, omp_lock_t() ) );
omp_init_lock( it->second );
}
return it->second;
}
void Sparse_Matrix_FL::setValue(unsigned int rid, unsigned int cid, double value)
{
omp_locker lock( getLock( rid, cid ) );
std::map<unsigned int, double>::iterator str = data_Matrix[rid].begin();
std::map<unsigned int, double>::iterator end = data_Matrix[rid].end();
while (str->first != cid && str != end) str++;
if (str != end)
if (value != 0)
str->second = value;
else
data_Matrix[rid].erase(str);
else
if (value != 0)
data_Matrix[rid][cid] = value;
}
Вам нужно будет вызвать omp_destroy_lock
для каждого элемента std::map
в конце вашей программы.