簡體   English   中英

多線程環境中靜態變量的C ++初始化

[英]C++ Initialization of static variable in multithreaded environment

我正在努力尋找一種正確的方法來初始化C ++中類的靜態成員。 上下文是隨機數生成。 我想要做的是創建一個用於隨機數生成的類,並為每個線程創建一個引擎。

現在看起來像這樣:

template<typename T, int MIN, int MAX>
class Rng {
 public:
  T operator()() {
    return get_random_number(omp_get_thread_num());
  }

 private:
  static T get_random_number(int id);
};

template<typename T, int MIN, int MAX>
T msl::Rng<T, MIN, MAX>::get_random_number(int id) {
  static std::vector<std::mt19937> engines;
  static std::vector<std::uniform_real_distribution<T>> dists;

  if (engines.empty()) { 
    int threads = omp_num_threads();
    engines.reserve(threads);
    dists.reserve(threads);

    for (int i = 0; i < threads; ++i) {
      std::random_device rd;
      std::mt19937 engine(rd());
      engines.push_back(engine);
      std::uniform_real_distribution<T> unif(MIN, MAX);
      dists.push_back(unif);
    }
  }

  return dists[id](engines[id]);
}

我這樣使用它:

int main(){

Rng<double, 0, 10> rng{};
auto init = rng();

int n = 100;
int a[n];

#pragma omp parallel for
  for(int i = 0; i < n; ++i){
    a[i] = rng();
  }
}

現在,我想擺脫main方法中的前期初始化(auto init = rng()),但是我不想引入不必要的開銷,即線程不應該互相等待,等等,因為目前初始化僅進行一次(顯然),但是生成發生了很多次。

我嘗試做的一件事是添加一個while循環,以便只有在第一次運行時,所有線程才會等待主線程初始化引擎:

template<typename T, int MIN, int MAX>
T msl::Rng<T, MIN, MAX>::get_random_number(int id) {
  static std::vector<std::mt19937> engines;
  static std::vector<std::uniform_real_distribution<T>> dists;

  int threads = omp_num_threads();

#pragma omp master
{
  if (engines.empty()) { 
    engines.reserve(threads);
    dists.reserve(threads);

    for (int i = 0; i < threads; ++i) {
      // init stuff...
    }
  }
}

  while(engines.size() < threads)
    continue; 

  return dists[id](engines[id]);
}

但是,這只會導致死鎖。 解決此問題的典型方法是什么? 我還考慮過使用互斥體和條件變量來喚醒線程,但是由於鎖定(實際上僅在第一次調用該函數時才需要),這可能代價很高。

典型的方法是使用構造函數

Rng構造 Rng執行這類初始化。

從字面上看,這就是它的工作。

仍然不清楚為什么首先要在這里擁有static數據。
為什么不使用成員變量

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM