- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 C++ 中,动态内存(取消)分配(malloc-free/new-delete)显然可以重复获得相同的内存范围,该内存范围被释放并按顺序再次分配。在多线程 C++ 中,这可能发生在多个线程中。
显然这样的重用不应该是用户的问题,他也不必关心;这是在“数据竞赛”[new.delete.dataraces]中指定的方式
For purposes of determining the existence of data races, the library versions of operator new, user replacement versions of global operator new, the C standard library functions aligned_alloc, calloc, and malloc, the library versions of operator delete, user replacement versions of operator delete, the C standard library function free, and the C standard library function realloc shall not introduce a data race ([res.on.data.races]). Calls to these functions that allocate or deallocate a particular unit of storage shall occur in a single total order, and each such deallocation call shall happen before the next allocation (if any) in this order.
最后一句很有意思:不仅内存范围的重用不会引起冲突,而且必须存在happen before (HB) 关系。虽然它没有说实现必须创建 HB 关系,而 HB 需求通常是对用户的需求,因为需求是有条件的并且基于实现创建的特殊情况(标准库代码),它似乎很明显,它只能被解释为对实现的要求。
这意味着在后续分配返回先前释放的内存位置的特殊情况下,与释放它的代码存在隐含的 HB 关系。
这是否真的意味着由执行释放的线程执行的任何内存操作的可见性可以预期极少由执行内存分配的代码保证?
这看起来像是给实现带来的一个非常奇怪的负担,只有非常奇怪的代码才能使用,这些代码会在其他线程取回这些相同地址的情况下记住已删除地址的拷贝(例如,所有同时不创建任何同步通过对指针表示的宽松原子 RMW 操作)。
真正的实现是否会真正提供这种可见性?内存分配函数是被视为“黑盒”函数,还是被编译器视为获取(释放)操作?
额外的精度
这是一个潜在的问题案例:编译器可以提供属性来指定函数的语义属性(如 GCC Common Function Attributes ),这些属性标识只能影响某些内存范围的函数(在当前“模块”中,这将是编程不变量的域:用户、stdlib、其他库...)。我承认我没有弄清楚细节,但从直觉上看它似乎是可行的,而且这些概念似乎对优化很有用。
如果实现必须跨分配提供此类保证,则注释将无效。
最佳答案
围绕此类分配无法保证任意内存操作的可见性。
每个取消/分配都需要相对于其他分配进行排序,并且返回与先前分配相同的内存的分配是明确排序的。但这并不意味着对发生在其间的其他操作进行排序。也就是说,它并不意味着所有其他操作的顺序一致性。
现在,可以看到其他操作,例如在释放之前发生的操作。但释放之前的所有内容都不会。
声明的要点是明确指出,如果您确实获得了与先前分配相同的内存地址,那么导致您到达那里的顺序肯定涉及涉及该地址的内存分配和释放。
规范有时必须相当迂腐。
That would look like an extremely odd burden to put on implementations
不是真的。可见性可能仅在内存取消/分配时才需要,但即使是可见性也不足为奇或繁重。
堆毕竟是共享资源。因此,作为共享资源,对它的访问往往会被锁定在某种互斥锁后面。大多数互斥锁确保所有锁定/解锁的完全可见。这一点很重要,因为管理堆需要编写堆管理数据,这些数据必须对尝试分配它的其他线程可见。因此,您需要一个相当广泛的内存屏障来完成您作为线程可访问分配器的工作。
而且它不像任何人将通用内存分配器误认为是快速操作。
因此,如果一个实现确实提供了完整的可见性,那很可能是因为管理堆内存需要它,而其他获得可见性的内存访问只是顺其自然。
Here is a potentially problematic case: the compiler could provide attributes to specify semantic properties of functions (like GCC Common Function Attributes) that identify functions that can only affect some memory range (in the current "module", which would be a domain of programming invariants: user, stdlib, other library...).
这样的函数无法调用编译器提供的通用内存分配器。根据定义,这样的函数需要对其使用的内存有严格的控制,而基本的内存分配器不会给你这个。因此,如果它需要动态分配,就必须使用专门的分配器,这样的分配器可以按照它想要的任何规则进行游戏。
关于c++ - 从理论上讲,仅在动态分配中使用内存范围的意外重用来同步线程是否(错误地)合法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56370961/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许在 Stack Overflow 上提出有关通用计算硬件和软件的问题。您可以编辑问题,使其成为
当我尝试在 db2 中创建表时,它抛出以下错误 $ db2 CREATE TABLE employee(emp_id INT NOT NULL, emp_name VARCHAR(100)) sh:
我有: while (i < l) { if (one === two) { continue; } i++; } 但是 JSLint 说: Problem at line 1 chara
所以我有这个代码: char inputs[10] = ""; int numInputs = 0; while (numInputs < 10){ char c; printf("E
var ninja = { name: 'Ninja', say: function () { return 'I am a ' + this.name; }
我收到一个我不明白的错误,请注意,我是编码新手,所以这可能是一个简单的错误。 #include using namespace std; int main() { //Initialise Fahr
我正在使用 javascript 和 react,由于某种原因,我收到了一个奇怪的 token 错误。 这是发生错误的代码: renderNavBar() { if (!this.us
Closed. This question is off-topic。它当前不接受答案。
由于某种我无法解释的原因,编译器正在输出一个错误,指出它发现了一个意外的#else 标记。 这发生在文件的开头: #if defined( _USING_MFC ) #include "stda
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
这个问题在这里已经有了答案: Difference between sh and Bash (11 个答案) 关闭 2 年前。 我正在编写一个简单的 bash 脚本,我在 XX `(' unexpe
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 此问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-topic
我在 Windows 7 上编写了一个脚本,它不断给我一个错误“(此时出乎意料。”对于以下代码 if %vardns%=="NODNS" ( netsh interface ipv4 set ad
我正在尝试使用xmlstarlet(使用xpath)解析XML文件,但是出现语法错误,并且我不知道如何更正我的代码。 这是我的脚本: #!/bin/bash if [ $1=="author" ];
以下脚本旨在在目录中的所有文件上运行程序“senna”,并将每个文件的输出(保留输入文件名)写入另一个目录 for file in ./Data/in/*; do ./senna -iobta
我从 challengers.coffee 运行此代码,并收到错误 ActionView::Template::Error (SyntaxError: [stdin]:3:31:unexpected
我在 config.db.database; 行中有语法错误(意外的标记“.”)。这是我在文件中的代码 const config = require('../config/config') const
这一定很明显,但是我无法使它正常工作。我正在尝试传输应该用于构建$ classKey的对象,这反过来又导致删除所需的软件(amd64或i386)。好吧,这里的代码: $name = @("softwa
我正在使用 1.3.7 版学习 Grails,但我一直无缘无故地遇到以下语法错误: unexpected token: mapping @ line x, column y. 有一次,我通过运行“gr
我正在尝试找出这段Pascal代码的问题 function Factorial(n: integer): integer; begin if n = 0 then Result := 1
我是一名优秀的程序员,十分优秀!