c++ - 对堆的访问是否序列化?

标签 c++ linux multithreading heap-memory

每个程序员很快就会了解多线程的一条规则是:

如果多个线程可以访问一个数据结构,并且至少有一个线程可能会修改该数据结构,那么您最好序列化对该数据结构的所有访问,否则您将面临调试痛苦的世界

通常,这种序列化是通过互斥锁完成的——即,想要读取或写入数据结构的线程会锁定互斥锁,做它需要做的任何事情,然后解锁互斥锁以使其再次可供其他线程使用。

这让我明白了这一点:进程的内存堆是一个可由多个线程访问的数据结构。这是否意味着对默认/非重载 newdelete 的每次调用都由进程全局互斥体序列化,因此是可能减慢速度的潜在序列化瓶颈多线程程序?或者现代堆实现是否以某种方式避免或缓解了这个问题,如果是,他们是如何做到的?

(注意:我标记了这个问题 linux,以避免正确但不具信息性的“它依赖于实现”的响应,但我也有兴趣了解 Windows 和如果实现之间存在显着差异,MacOS/X 也会这样做)

最佳答案

newdeletethread safe

The following functions are required to be thread-safe:

  • The library versions of operator new and operator delete
  • User replacement versions of global operator new and operator delete
  • std::calloc, std::malloc, std::realloc, std::aligned_alloc, std::free

Calls to these functions that allocate or deallocate a particular unit of storage occur in a single total order, and each such deallocation call happens-before the next allocation (if any) in this order.

使用 gcc,new 是通过委托(delegate)给 malloc 来实现的,我们看到他们的 malloc 确实是 use a lock .如果您担心分配会导致瓶颈,请编写自己的分配器。

关于c++ - 对堆的访问是否序列化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56196399/

相关文章:

linux - 如果有多个默认值,linux如何选择使用哪个网关?

c++ - 如何动态确定libudev版本

ios - 如何在swift 4中使用线程

sql - Rails/SQL 如何让不同的工作人员处理不同的记录?

c++ - Qt - 错误 : unknown module networkauth

c++ - 线程安全与迭代器有效性

c++ - gnu++0x 标准的 GNU 版本问题

c++ - 简化 cout << "mkdir: cannot create directory ' "<< arguments[1] << "' : File exists\n";

linux - 如何识别孤立的 veth 接口(interface)以及如何删除它们?

android - 哪个线程调用 `onCreateLoader()` 和 `onLoadFinished()`?