指向 std::map 中值的指针

发布于 2024-07-26 16:46:37 字数 861 浏览 5 评论 0原文

我有一个 std::map ,多个线程使用它来存储数据。 该映射是这样声明的:

std::map<int, Call> calls;

从每个线程,我必须获取互斥锁,获取属于该线程的对象的指针或引用,然后释放互斥锁。 之后我可以修改该对象,因为每个对象仅由一个线程使用。 一旦线程死亡,映射中相应的对也会被删除。

我想知道实现这一点的最佳方法。 我正在考虑两种方法:

1)我知道这个可能看起来非常疯狂,但仍然

std::map<int, Call> calls;
...

{
    mutex.lock();
    Call* callptr = &calls[id];
    mutex.unlock();

   // use callptr
}

或者2)我认为这个看起来更明智

std::map<int, std::auto_ptr<Call> > calls;

...

{
    mutex.lock();
    std::auto_ptr<Call> callptr = map[id];
    mutex.unlock();

    // use callptr

    mutex.lock();
    map[id] = callptr;
    mutex.unlock();
}

线程实际上是在不同的dll中创建的,我没有相应的代码。 我现在正在编写的这个 dll 由该 dll 导入并使用。 因此它必须仅使用 std::map 来实现,但是任何人都可以告诉我这些方法之一是否可以或者是否有方法使其更稳定。

谢谢

I have a std::map that is used by multiple threads to store data. The map is declared like this:

std::map<int, Call> calls;

From each thread, I have to acquire a mutex lock, obtain a pointer or reference to the object belonging to that thread, then release the mutex lock. I can modify the object after that because each object is used only by one thread. As soon as the thread dies, the corresponding pair in the map would also get deleted.

I would like to know the best way to implement this. I was thinking of two ways:

1) I know this one could look outrageously crazy, but still

std::map<int, Call> calls;
...

{
    mutex.lock();
    Call* callptr = &calls[id];
    mutex.unlock();

   // use callptr
}

or 2) I think this one looks more sensible

std::map<int, std::auto_ptr<Call> > calls;

...

{
    mutex.lock();
    std::auto_ptr<Call> callptr = map[id];
    mutex.unlock();

    // use callptr

    mutex.lock();
    map[id] = callptr;
    mutex.unlock();
}

The threads actually are created in a different dll and I don't have the code for that. This dll that I'm writing now gets imported by that dll and used. So it has to be implemented with std::map only, but could anyone tell me if one of these methods is ok or if there are ways to make it more stable.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

稳稳的幸福 2024-08-02 16:46:37

您应该使用迭代器:

mutex.lock();

std::map<int, Call>::iterator callptr = calls.find(id);
callptr->second.foo();
...

mutex.unlock();

您的第一个使用指针的解决方案是有问题的,因为映射中对象的生命周期是不确定的 - 当插入或删除元素时重新平衡树时,它可能会被移动。

您的第二个解决方案根本不起作用,因为 std::auto_ptr 不满足 std::mapmapped_type 的要求 - 大多数情况下因为它的复制构造函数和operator=实际上并不复制。 您可能不会收到编译器错误,但您会在运行时收到非常奇怪的行为。

You should use iterators:

mutex.lock();

std::map<int, Call>::iterator callptr = calls.find(id);
callptr->second.foo();
...

mutex.unlock();

Your first solution with pointers is problematic, because the lifetime of the object in the map is uncertain - it may be moved when the tree is rebalanced when elements are inserted or deleted.

Your second solution won't work at all, because std::auto_ptr does not fulfil the requirements for mapped_type of std::map - mostly because its copy constructor and operator= don't actually copy. You likely won't get a compiler error, but you'll get very weird behavior at run-time.

意犹 2024-08-02 16:46:37

根据我的说法 线程本地存储 是最适合您的选择。

如果您需要线程特定的数据,则可以使用线程本地存储并完全消除对映射和互斥锁定的需要。

According to me Thread Local storage is the best option for you.

If you need thread specific data, you can make use of Thread Local Storage and completely eliminate the need for map and mutex locking.

渡你暖光 2024-08-02 16:46:37

不要在 STL 容器中使用 auto_ptr。 不。 实际上,实现者需要尝试并使其在出现编译错误时使用。 标准容器倾向于复制周围的东西。 auto_ptr 的做法是非常错误的。

Don't use auto_ptr's in STL containers. DON'T. The implementors are actually required to try and make its use there a compilation error. Standard containers tend to copy things around. That's a very wrong thing with auto_ptr.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文