Tag: 内存模型

可以使用C11围栏来推断其他线程的写入吗?

图4b中的Adve和Gharachorloo的报告提供了以下在没有顺序一致性的情况下表现出意外行为的程序示例: 我的问题是,是否有可能只使用C11栅栏和memory_order_relaxed加载和存储来确保register1(如果写入)将被写入值1.抽象中可能难以保证的原因是P1,P2并且P3可以在病理性NUMA网络中的不同点处具有P2在P3之前看到P1的写入的属性,但是不知何故P3看到P2的写入非常快。 特别是对C11规范难以保证的原因是P1写入A和P2的A读取不会相互同步,因此规范的5.1.2.4.26段将导致未定义的行为。 可能我可以通过放松的primefaces提取/存储来回避未定义的行为,但我仍然不知道如何对P3所看到的顺序进行过渡性推理。 下面是一个试图用栅栏解决问题的MWE,但我不确定它是否正确。 我特别担心释放栅栏不够好,因为它不会刷新p1的存储缓冲区,只是p2的。 但是,它会回答我的问题,如果你可以认为断言永远不会失败只是基于C11标准(而不是一些关于特定编译器和架构的其他信息)。 #include #include #include #include atomic_int a = ATOMIC_VAR_INIT(0); atomic_int b = ATOMIC_VAR_INIT(0); void p1(void *_ignored) { atomic_store_explicit(&a, 1, memory_order_relaxed); } void p2(void *_ignored) { if (atomic_load_explicit(&a, memory_order_relaxed)) { atomic_thread_fence(memory_order_release); // not good enough? atomic_store_explicit(&b, 1, memory_order_relaxed); } } void p3(void *_ignored) { int register1 = 1; if (atomic_load_explicit(&b, […]

此示例是否包含数据竞争?

这是原始问题,但我的问题有些不同。 C ++内存模型 – 此示例是否包含数据竞争? 我的问题: //CODE-1: initially, x == 0 and y == 0 if (x) y++; // pthread 1 if (y) x++; // pthread 2 注意:上面的代码是用C语言编写的,而不是用C ++编写的(没有内存模型)。 那么它是否包含数据竞争? 从我的观点来看:如果我们在顺序一致性内存模型中查看代码,则没有数据竞争,因为x和y将永远不会同时为非零。 但是,我们永远不能假设顺序一致性内存模型,因此编译器重新排序可以进行相对于线程内正确性的转换,因为编译器不知道线程的存在…….对吗? 所以代码可以转换为: //CODE-2 y++; if (!x) y–; x++; if (!y) x–; 上面的转换并没有违反顺序正确性所以它是正确的。这不是编译器的错,对吧? 所以我同意CODE-1包含数据竞争的观点。你呢? 我有一个额外的问题,带有内存模型的C ++ 11可以解决这个数据竞争因为编译器知道线程,所以他们会根据内存模型类型进行重新排序,对吧?

字符串常量与C中的char数组

可能重复: C中的char s []和char * s有什么区别? 更多的是一般性问题,而不是试图解决问题,我一直在阅读C编程语言书,他们注意区分 char amessage[] = “blah”; char *pmessage = “blah”; 一个是char数组,另一个是指向字符串常量的指针。 他们说修改char数组是可以接受的,但你不应该修改字符串常量,因为它会触发未定义的行为。 我的问题是:不是以与char数组相同的方式存储在内存中的字符串常量吗? 为什么我可以修改它 char *p = “this is a string constant”; *(p+2) = ‘a’; printf(“%s”, p); 如您所料,结束打印“thas是一个字符串常量”。 我可以理解它是如何有意义的,因为字符串常量不应该最终在运行时被更改,因为它可能会混淆其他人/你自己处理你的代码并不期望它的价值改变,但纯粹function性的术语是什么错误的什么是可能触发的未定义行为,以及当char数组不能时它会如何机械地适得其反? 我只是想知道我是否遗漏了一些关于字符串常量如何在内存中工作以及编译器如何看到它们的内容。

Delphi是否有任何与C的volatile变量等价的东西?

在C和C ++中,变量可以标记为volatile ,这意味着编译器不会对其进行优化,因为它可以在声明对象外部进行修改。 在Delphi编程中是否有相同的东西? 如果不是关键字,也许可以解决? 我的想法是使用绝对 ,但我不确定,这可能会引入其他副作用。

在C / C ++中,volatile变量是否保证最终在线程之间具有一致的语义?

任何通常遵循的标准(ISO C或C ++,或任何POSIX / SUS规范)是否有任何保证,由多个线程访问的变量(可能标记为volatile)(未被互斥锁保护)将最终保持一致如果分配给? 要提供一个特定示例,请考虑共享变量v的两个线程,初始值为零。 线程1:v = 1 线程2:while(v == 0)yield(); 线程2是否保证最终终止? 或者它可以想象永远旋转,因为缓存一致性永远不会启动并使得赋值在线程2的缓存中可见? 我知道C和C ++标准(在C ++ 0x之前)完全没有关于线程或并发的说法。 但我很好奇,如果C ++ 0x内存模型,或pthreads,或其他任何东西,保证这一点。 (显然这确实可以在Windows上运行32位x86;我想知道它是否可以依赖于某些东西,或者它是否恰好在那里工作)。