首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >无锁队列中的内存管理

无锁队列中的内存管理
EN

Stack Overflow用户
提问于 2011-06-23 22:14:37
回答 5查看 2.5K关注 0票数 6

我们一直希望在代码中使用一个无锁队列来减少当前实现中单个生产者和使用者之间的锁争用。有很多队列实现,但我还不太清楚如何最好地管理节点的内存管理。

例如,生产者的样子如下:

代码语言:javascript
运行
复制
queue.Add( new WorkUnit(...) );

消费者看起来:

代码语言:javascript
运行
复制
WorkUnit* unit = queue.RemoveFront();
unit->Execute();
delete unit;

我们目前使用内存池进行分配。您会注意到,生产者分配内存,使用者删除它。由于我们使用的是池,因此需要向内存池添加另一个锁,以正确地保护它。这似乎一开始就否定了无锁队列的性能优势。

到目前为止,我认为我们的选择是:

  • 实现一个无锁内存池.
  • 转储内存池并依赖线程安全分配器。

我们还有其他的选择可以探索吗?我们试图避免实现一个无锁的内存池,但我们可能会选择这条路。

谢谢。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-06-23 22:30:51

只有生产者才能创建对象并在不再需要时销毁它们,。使用者只能使用对象并将其标记为已使用的对象。这就是问题所在。在这种情况下,您不需要共享内存。这是我所知道的高效无锁队列实现的唯一方法。

阅读的伟大文章,其中详细描述了这种算法。

票数 4
EN

Stack Overflow用户

发布于 2011-06-23 22:57:18

另一种可能是为每个线程拥有一个单独的内存池,因此只有一个线程使用堆,您可以避免锁定分配。

这样您就可以管理一个释放块的无锁函数了。幸运的是,这很容易管理:您为每个堆维护了一个空闲块的链接列表。您将块自己的地址放入链接列表的链接字段(您将用作内存),然后与指针进行原子交换,指针保存链接列表的头。

票数 1
EN

Stack Overflow用户

发布于 2011-06-23 22:31:51

你应该看看英特尔的TBB。我不知道商业项目要花多少钱,但是他们已经有了并发队列,并发内存分配器,诸如此类的东西。

队列接口看起来也很不可靠--例如,您的RemoveFront()调用--如果队列是空的怎么办?newdelete调用看起来也相当冗余。英特尔的TBB和微软的PPL (包括在VS2010中)没有受到这些问题的影响。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6461236

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档