原子的使用是否正确?

时间:2015-02-27 18:30:18

标签: c++ multithreading locking atomic

我有以下层次结构:

struct Point
{
  std::atomic<int> x;
  std::atomic<int> y;
  std::atomic<int> z;
}

class Data
{
 std::atomic<int> version;
 Point point;
}

unordered_map<std::string,Data> hashtable; // global

Thread1是制作人:

线程1收到std::pair<std::string,Point> new_data,它确实:

shared_hashtable[new_data.first].point.x.store(new_data.second.x,memory_order_release) // update X 
shared_hashtable[new_data.first].point.y.store(new_data.second.y,memory_order_release) // update Y
shared_hashtable[new_data.first].point.z.store(new_data.second.z,memory_order_release) // update Z
hashtable[new_data.first].version.store(hashtable[new_data.first].version+1,memory_order_release) // update the version of the data

线程2:

int local_version;
while(local_version!=shared_hashtable["string1"].version.load(memory_order_acquire))
{
  //...process data...
 local_version=shared_hashtable["string1"].version.load(memory_order_acquire);
 }

传递的内存顺序是否保证我的存储和加载不会被重新排序。 设计是否按预期工作:如果hastable["string1"]处的对象更新,我是否会处理线程2中的相应数据?

2 个答案:

答案 0 :(得分:2)

hashtable未受到同步访问保护,其operator[]不是const。如果您保证在这两个线程尝试访问它之前将(1)hashtable["string1"]插入到表中,并且(2)在这两个线程运行期间没有其他线程写入hashtablehashtable中的查找不会导致数据竞争。如果您不能保证(1)和(2),那么您需要使用互斥锁保护查找。 unordered_map在重新哈希时使迭代器无效,但引用保持有效,直到从地图中删除引用的项目。

内存模型保证,在memory_order_releaseversion读取memory_order_acquire中的相应值之后,线程2中可以看到线程1中写入version写入Point之前的写入。 }。即使对Point成员的访问是非原子的,也是如此。

但是,线程2中Point成员的读取可能会在线程1中看到以后写入的值,因此不能保证三个{{1}在线程2中读取的成员对应于线程1实际写入的特定Point。我想你需要保证线程2处理的Point实际上是Point由线程1编写而不是多个不同点的值的集合(例如,版本1的x,版本2的y,版本3的z。改变设计

struct Point { atomic<int> x, y, x; };

struct Point { int x, y, x; };
struct Data {
  atomic<int> version;
  atomic<Point> point;
};

将确保Point读取实际上是Point。当然,它不一定是Point对应于给定的versionpoint可能已经被线程1中的以后的版本覆盖了线程2到处读取它的时间。这可能导致同一点被线程2处理两次,一次使用陈旧版本,再次使用适当版本再次处理。如果您需要确保每个版本最多只处理一次,则必须验证{<1}}在读取version之后是,因为它是之前 em>阅读point

总而言之,我们得到了这个程序(DEMO):

point

答案 1 :(得分:1)

你可以试试 https://github.com/Taymindis/atomic_hashtable

用于读取,写入和删除的哈希表,而不进行锁定,而多线程在缓冲区上执行操作,简单和稳定

Readme.md中提供的API文档