簡體   English   中英

與函數中的靜態變量競爭條件

[英]Race condition with a static variable in a function

我有以下功能:

int helper(int id) {
  static std::map<int,int>* lookup_table = new std::map<int,int>();

  // Modify lookup_table

  return (it == lookup_table->end()) ? -1 : 0;
}

helper在多個線程中被調用。 防止lookup_table競爭條件的方法是什么?

這是否足夠?

static std::mutex helper_lock;

int helper(int id) {
  static std::map<int,int>* lookup_table = new std::map<int,int>();

  helper_lock.lock();
  // Modify lookup_table
  helper_lock.unlock();

  return (it == lookup_table->end()) ? -1 : 0;
}

這還不夠。 對 STL 容器的修改有可能使其迭代器失效,因此如果另一個線程正在修改表,則在函數末尾與lookup_table.end()的比較可能會失效。

簡單的解決方案是在比較完成后才解鎖。 (請注意,我使用std::unique_lock<std::mutex>進行鎖定 - 當unique_lock超出范圍時釋放鎖定

static std::mutex helper_lock;

int helper(int id) {
  static std::map<int,int>* lookup_table = new std::map<int,int>();

  std::unique_lock<std::mutex> lock(helper_lock);
  // Modify lookup_table
  // explicit unlock is not required, lock is released when lock is destroyed

  return (it == lookup_table->end()) ? -1 : 0;
}

更復雜的解決方案是使用允許讀/寫鎖的shared_mutex 無論如何,這可能是您想要的,因為您肯定有正在讀取查找表的進程? 您可以在讀取和取消引用end()迭代器之前應用讀取鎖定。 多個線程將能夠一次讀取數據,但在所有讀取器都被釋放之前不允許寫入。

static std::shared_mutex helper_lock;

int helper(int id) {
  static std::map<int,int>* lookup_table = new std::map<int,int>();

  {
    std::unique_lock<std::shared_mutex> lock(helper_lock);
    // Modify lookup_table
    // explicit unlock is not required, lock is released when lock is destroyed
  }

  // acquire read-only lock, but not if any thread holds a unique_lock
  std::shared_lock<std::shared_mutex> lock(helper_lock);
  return (it == lookup_table->end()) ? -1 : 0;
}

暫無
暫無

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

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