简体   繁体   English

C ++中的线程安全性

[英]Thread safety in C++

I have question regarding thread safety as below ( I have only two threads in which one of the threads only read from the map, the other threads would be writing and reading as shown): 我有关于线程安全的问题如下(我只有两个线程,其中一个线程只从地图读取,其他线程将写入和读取如图所示):

//Thread 2: the reading and writing thread
unordered_map<int, unordered_map<classA*>*>testMap;

//need lock because writing to the map?
testMap[1] = new unordered_map<int, classA*>;

//do not need lock because only reading and the other thread is only reading?
unordered_map<classA*>* ptr = testMap[1];

//need lock because writing?
(*ptr)[1] = new classA;

//do not need lock because only reading and the other thread is only reading?
classA* ptr2 = (*ptr)[1];

//din't modify the map, but modify the data pointed by the pointer stored by the map, do I need lock?
ptr2->field1 = 5;
ptr2->field2 = 6;

//end of reading and writing thread

What is the correct way to lock to unordered_map? 锁定到unordered_map的正确方法是什么? Also, should I use a single lock or multiple locks? 另外,我应该使用单个锁还是多个锁?

Thanks. 谢谢。

If your map is the only shared resource, a single mutex is sufficient. 如果您的地图是唯一的共享资源,则只需一个互斥锁即可。

You need to lock the writing in the first thread, and lock the reading in the second one. 您需要锁定第一个线程中的写入,并将读取锁定在第二个线程中。 If you lock the map only when writing on it, the second thread could read it while you are writing in it. 如果仅在写入时锁定地图,则第二个线程可以您写入时读取它。

You dont need a lock in the last example regarding the pointers, since you dont deal with any data stored in the map. 在最后一个关于指针的例子中你不需要锁,因为你不处理存储在地图中的任何数据。 Edit : in fact, it depends on what your are doing with the pointers and in which thread you do it. 编辑:事实上,它取决于你在使用指针做什么以及在哪个线程中执行它。

You should read this great article : http://herbsutter.com/2010/09/24/effective-concurrency-know-when-to-use-an-active-object-instead-of-a-mutex/ 你应该阅读这篇很棒的文章: http//herbsutter.com/2010/09/24/effective-concurrency-know-when-to-use-an-active-object-instead-of-a-mutex/

You need to lock both, reading and writing. 你需要锁定,阅读和写作。 If you do not lock reading then a write can occur while you are reading and you may access the map in an inconsistent state. 如果您没有锁定读取,则在您阅读时可能会发生写入,并且您可能会以不一致的状态访问地图。

What would be best in your situation would be a reader-writer-lock. 在你的情况下最好的是读者 - 作家锁。 Such a lock allows multiple readers to read at the same time but only one writer at the same time and no readers while a writer writes and vice versa. 这样的锁允许多个读取器同时读取但同时只读取一个写入器而写入器写入时没有读取器,反之亦然。

Couple of things: 几件事:

  1. You should consider smart pointers to store in your map. 您应该考虑在地图中存储智能指针。
  2. What you are doing is potentially quite dangerous (ie you may not be modifying the main map), but you are modifying what's stored there and if you do this outside of a lock, the end result could be anything - let's say that thread one has also read the same pointer and starts iterating whilst thread two is writing the instance of classA - what happens then? 你正在做的事情可能是非常危险的(也就是说你可能没有修改主地图),但是你正在修改存储在那里的内容,如果你在锁定之外这样做,最终的结果可能是任何东西 - 让我们说线程一有也读取相同的指针并开始迭代,而线程二正在编写classA的实例 - 那么会发生什么?

I would have a lock around the main map, and then another lock for each payload map. 我会在主地图周围锁定,然后为每个有效负载地图锁定另一个锁。 Any operations on either map should require to obtain the lock at the correct level. 任何一个地图上的任何操作都需要获得正确级别的锁定。 I'd also be careful not to return iterators outside of the class that manages the lock, so basically you should implement all the methods you'd need within the class. 我还要注意不要在管理锁的类之外返回迭代器,所以基本上你应该实现你在类中需要的所有方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM