c++ - 在非线程安全容器中访问指针指向的值(线程安全映射中的条目)是否可以?

标签 c++ multithreading c++11 thread-safety boost-thread

例如,

// I am using thread safe map from
// code.google.com/p/thread-safe-stl-containers
#include <thread_safe_map.h>

class B{
  vector<int> b1;
};

//Thread safe map
thread_safe::map<int, B> A;
B b_object;
A[1] = b_object;

// Non thread safe map.
map<int, B*> C;
C[1] = &A[1].second;

那么下面的操作仍然是线程安全的吗?

Thread1:
for(int i=0; i<10000; i++) {
  cout << C[1]->b1[i];
}

Thread2:
for(int i=0; i<10000; i++) {
  C[1]->b1.push_back(i);
}

上面的代码有没有问题?如果是这样,我该如何解决?

是否可以在非线程安全容器中访问指针指向的值(线程安全映射中的条目)?

最佳答案

不,你在那里做的事不安全。 thread_safe_map 的实现方式是在每次函数调用期间锁定:

//Element Access
T & operator[]( const Key & x ) { boost::lock_guard<boost::mutex> lock( mutex ); return storage[x]; }

一旦访问函数结束,锁就会被释放,这意味着您通过返回的引用所做的任何修改都没有保护。

除了不完全安全之外,这种方法非常慢。

此处提出了一种安全(呃)、高效但高度实验性的方式来锁定容器:https://github.com/isocpp/CppCoreGuidelines/issues/924 这里有源代码 https://github.com/galik/GSL/blob/lockable-objects/include/gsl/gsl_lockable (无耻的 self 推销免责声明)。

关于c++ - 在非线程安全容器中访问指针指向的值(线程安全映射中的条目)是否可以?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50830052/

相关文章:

c++ - 共享指针的双重检查锁定

java - 隐藏实现细节是封装还是抽象?

c++ - 如果未链接使用代码,则未定义对 g++ 中静态常量成员的引用

c++ - 获取 QWidget 的 Windows 消息而不对其进行子类化并重新实现 QWidget::winEvent

c# - C# 中的生产者-消费者队列中的 ArgumentException

c# - 了解 C# 中具有 "ContinueWith"行为的异步/等待与等待

c++ - 手写递归上升解析器中的递归左递归

c++ - Arduino IDE 无法识别 .c 文件是 .cpp

c++ - 我的编程面试题: Reverse a string and find the mode of an array

c++ - 如何在C/C++中从外部库调用函数