我正试图获取矩阵中每个元素的锁,为此我编写了以下代码:
std::map<unsigned int, omp_lock_t> ds_lock;
void Sparse_Matrix_FL::setValue(unsigned int rid, unsigned int cid, double value)
{
omp_set_lock(&ds_lock(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_unset_lock(&ds_lock(rid,cid));
}
但我得到了错误:
类类型的对象的调用,但没有适当的运算符((或将函数转换为指向函数类型的指针
这是另一个错误。
term不计算为具有2个参数的函数
我不明白我哪里做错了。
您可以通过下标运算符[]
或使用find
方法查找std::map
元素。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;
}
在程序结束时,您需要对std::map
的每个元素调用omp_destroy_lock
。