C++删除对象时,是否会锁定?

3

使用C++创建新对象时,'new'关键字会进行一些锁定操作(因为它会进行一些内存分配等操作)。因此,在无锁软件中不能直接使用它。

但是,'delete'关键字是否会创建任何类型的锁呢?

我仍在使用C++98,我认为它在C++11中的工作方式也相同。


请查看此链接 https://dev59.com/SXE85IYBdhLWcg3wSxkv - Wander3r
我认为不会,删除调用析构函数并简单地忽略它曾经实例化的内存块。等待有人扩展。 - someone_ smiley
2个回答

2
new中使用锁的原因,正如你所说,是内存分配。如果分配需要锁定,则在某些情况下,相应的释放也可能需要锁定。当然,即使分配需要锁定,释放也可能是无锁的。
请注意,delete本身并不锁定(new也不锁定),而是底层原语会锁定。因此,如果您有一个无锁分配器,那么使用newdelete就没有问题了。[当然,前提是构造函数和析构函数都是无锁的]。
请注意,放置形式的newdelete不应该锁定。
避免使用newdelete(或至少避免分配)可能会限制您的许多操作。例如,除了C++11中的std::array之外,所有容器都将执行分配,因此不能使用std::vectorstd::stringstd::map等。许多构造函数为创建的对象执行分配。当然,除了newdelete之外,其他函数中可能也有锁定- I/O函数通常具有锁定以防止完全混乱的输出(但不一定保证整个输出不会混乱)。几乎任何使用共享资源的东西都可能在某个级别上有锁定,无论是在操作系统内部还是在用户模式级别。
C++标准在这方面并没有给出具体说明,这是一个实现细节。

感谢您的详细解释 :) - Juan JuezSarmiento
整个程序不必完全无锁。只要您不在“热点”代码中增加它,就可以使用std::vector。即使每个线程都在增长自己的std::vector,它也会呈指数增长,因此来自不同线程的竞争分配器锁的争用应该非常少,除非它们全部以锁步方式增长/缩小。(因此,每个线程的向量大小相同,并且将同时重新分配。)无论如何,在vector上的operator []是可以的。(您不能创建共享的std::vector,也不要考虑atomic<vector<int>>,那很慢。) - Peter Cordes
彼得,问题是我正在编写一个VST插件,其中音频线程需要100%无锁。界面可能会有锁定。 - Juan JuezSarmiento

1
C++98标准没有多线程的概念,实现线程安全由具体实现决定。此外,该标准仅指示程序应该如何行为。例如,有些实现在调用delete时实际上不会释放内存给操作系统。因此,在C++98中,它可能不会锁定,但这是与具体实现无关的。在C++11中,情况大不相同,因为该标准引入了多线程的概念。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接