C++ 是呼叫接线员';删除';同步的

C++ 是呼叫接线员';删除';同步的,c++,memory-management,asynchronous,C++,Memory Management,Asynchronous,我想知道对操作员delete的呼叫是否同步。换句话说,如果我这样做: delete p; < C++标准是否保证只有在这个调用完成后,内存才释放?或者,调用是异步的,只是为操作系统安排了一个任务,以便在它决定这是释放内存的最佳时间时立即释放内存 如果第一种情况是有效的,那么这是否意味着我们必须实现自己的异步删除工具?我这样问是因为我想说,大多数时候,我们(程序员)并不关心内存何时被完全释放,因此我们不希望我们的代码冻结并等待这个(最可能昂贵的?)系统调用完成,而是安排删除任务并立即继续执行。C

我想知道对操作员
delete
的呼叫是否同步。换句话说,如果我这样做:

delete p;
< C++标准是否保证只有在这个调用完成后,内存才释放?或者,调用是异步的,只是为操作系统安排了一个任务,以便在它决定这是释放内存的最佳时间时立即释放内存


如果第一种情况是有效的,那么这是否意味着我们必须实现自己的异步删除工具?我这样问是因为我想说,大多数时候,我们(程序员)并不关心内存何时被完全释放,因此我们不希望我们的代码冻结并等待这个(最可能昂贵的?)系统调用完成,而是安排删除任务并立即继续执行。C++提供了任何标准的工具(也许通过标准库?)来完成这一过程而不重新发明轮子?

< P>就你而言,一切都是按你的预期行事的,没有隐藏的陷阱或陷阱。你可以说
T*p=newt;删除p这是正确的,无论在什么情况下发生

考虑到操作系统通常必须同时为各种进程和线程分配内存,您可以假设这个问题已经得到了正确的解决

更正式地说,18.6.1.4/1(“数据竞赛”)说:

为了确定数据竞争的存在,库版本的
operator new
,用户替换版本的global
operator new
,而C标准库函数
calloc
malloc
的行为应如同它们只访问和修改了返回值引用的存储一样。图书馆版本 对于
操作员删除
,用户替换版本的
操作员删除
,以及C标准库函数
免费
,其行为应与仅访问和修改其第一个参数引用的存储一样


关于“阻塞性”:这一切归结为C库的分配函数的作用。除“此函数返回指向某个内存的指针”外,未指定任何内容。这取决于平台如何提供内存分配。

delete
是同步的。现在,这并不意味着底层内存实际上是在那时被操作系统释放的,但是从C++系统的角度来看,它的行为好像是.< /P> 我这样问是因为我想说,大多数时候,我们(程序员)并不关心内存何时被完全释放


但是
delete
主要不是关于内存,它同样是关于以确定性的方式调用析构函数——它是一种通用的资源释放机制,不限于内存。这里有同步性是很重要的,否则C++的核心方面之一是不起作用。

< P>在C/C++中的自由调用无论怎样都已经非常快了。 在这方面,您没有理由推迟删除它的时间。 为此,你需要做的任何簿记都会抵消实际的免费通话时间


如果析构函数做更多的工作,比如关闭DB连接的套接字,那么您可以在以后做这类工作,但这应该是一种例外情况。

没有任何东西可以保证
删除p
会将内存释放回操作系统——永远不会。事实上,在相当多(大多数?)的实现中,它不会做类似的事情


但是,调用
delete
时发生的具体情况各不相同——在某些情况下几乎是即时的(只需将块链接到可用内存块列表)。在其他情况下,它做的工作更多:销毁对象,或者搜索当前可用列表中可以与被释放块合并的相邻块。

我想他是在问对
delete
的调用是否是阻塞,而不是线程安全。是的,我对它是否是阻塞感兴趣。@AndrewDurward:我不认为这可以从问题内部得到答案,至少在你更明确地理解“阻塞”的含义之前是这样。在单线程MS-DOS上,答案很可能是“否”,但在多任务系统上,您总是可以取消调度。@Haroogan:正如我所说,操作系统必须同时管理每个进程的内存,因此它必须在某个时间点进行同步。但一个好的操作系统应该确保没有单个进程或线程因内存分配而耗尽。不过,您必须查阅操作系统的文档,以及您的C库实现。请定义“内存已释放”如果您想定义何时应该释放,请使用自己的
new
delete
操作符。当你有许多小对象时,这是很常见的。释放内存比分配内存要便宜得多。如果你想要异步删除,你可以使用
std::unique_ptr
并使用自定义的删除器。我喜欢你的解释,这绝对有意义+1、我甚至不认为C++中有什么关于“异步”的概念,这在OP中是有意义的(比如异步I/O)。(只有关于线程和内存模型的内容。)所以我不想在整个概念都没有定义的情况下说“X是同步的…”KerrekSB这是一个很好的观点。在一个没有定义异步语义的领域里,很难谈论异步语义。@Konrad Rudolph:当然,我知道析构函数是以确定的方式调用的,否则,正如你所说,在语言级别上释放资源的原则根本不可能实现。但是,举例来说,当整个析构函数链(同步的)完成执行时,这并不意味着这些对象(调用析构函数的对象)占用的实际内存实际上已被释放。是t吗