繁体   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