简体   繁体   English

与函数中的静态变量竞争条件

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

I have the following 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 is called in multiple threads. helper在多个线程中被调用。 What is the way to prevent a race condition for lookup_table ?防止lookup_table竞争条件的方法是什么?

Would this be sufficient?这是否足够?

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

That will NOT be sufficient.这还不够。 Modifications to an STL container have the potential to invalidate its iterators, so the comparison to lookup_table.end() at the end of the function might be invalidated if another thread is modifying the table.对 STL 容器的修改有可能使其迭代器失效,因此如果另一个线程正在修改表,则在函数末尾与lookup_table.end()的比较可能会失效。

The easy solution is to only unlock after the comparison is done.简单的解决方案是在比较完成后才解锁。 (note that I'm using std::unique_lock<std::mutex> to do the locking - lock is released when the unique_lock goes out of scope (请注意,我使用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;
}

A more complicated solution is to use a shared_mutex that allows a read/write lock.更复杂的解决方案是使用允许读/写锁的shared_mutex This is likely what you want anyway, since certainly you have processes that are reading the lookup table?无论如何,这可能是您想要的,因为您肯定有正在读取查找表的进程? You can apply the read-lock before the end() iterator is read and dereferenced.您可以在读取和取消引用end()迭代器之前应用读取锁定。 Multiple threads will be able to read the data at once, but none are allowed to write until all readers are released.多个线程将能够一次读取数据,但在所有读取器都被释放之前不允许写入。

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