首页 > 解决方案 > 术语不会评估为采用 2 个参数的函数

问题描述

我正在尝试获取矩阵中每个元素的锁,为此我编写了以下代码:

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));
}

但我得到了错误:

在没有适当的 operator() 或将函数转换为指针函数类型的情况下调用类类型的对象

这是另一个错误。

术语不计算为带 2 个参数的函数

我不明白我在哪里做错了。

标签: c++openmp

解决方案


std::map您可以通过下标运算符[]或使用方法查找元素findstd::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


推荐阅读