小编Mat*_*att的帖子

在多核系统的可移植C代码中,“ volatile”是否可以保证任何东西?

看着经过一大堆 其他 问题 他们的 答案,我得到的印象是有什么在C“挥发性”关键字表示正好没有广泛的协议。

即使标准本身似乎也不够清晰,以至于每个人都无法理解其含义

除其他问题外:

  1. 根据您的硬件和编译器,它似乎提供了不同的保证。
  2. 它影响编译器优化,但不影响硬件优化,因此在执行自己的运行时优化的高级处理器上,甚至不清楚编译器是否可以阻止您要阻止的任何优化。(某些编译器确实会生成指令来阻止某些系统上的某些硬件优化,但这似乎并未以任何方式进行标准化。)

总结一下问题,似乎(经过大量阅读)“ volatile”保证了类似的结果:该值将不但从/向寄存器,而且至少向内核的L1缓存中读/写,其顺序与读/写出现在代码中。但这似乎没有用,因为在同一线程内从寄存器中读取/写入寄存器已经足够,而与L1缓存进行协调并不能保证与其他线程进行协调。我无法想象仅与L1缓存进行同步的重要性。

用途1
唯一广泛同意使用volatile的似乎是旧的或嵌入式系统,其中某些内存位置通过硬件映射到I / O功能,例如内存中的某个位(直接在硬件中)控制灯光。 ,或内存中的某个位告诉您键盘键是否按下(因为它是通过硬件直接连接到键的)。

看来,“用1”不移植的代码,其目标包括多核系统发生。

USE 2
与“ use 1”没什么不同,是可由中断处理程序(可以控制灯光或存储来自按键的信息)随时读取或写入的内存。但是为此已经存在一个问题,即取决于系统,中断处理程序可能会在 具有自己的内存缓存的不同内核运行,并且“ volatile”不能保证所有系统上的缓存一致性。

因此,“使用2”似乎超出了“易失性”所能提供的范围。

用途3
我看到的唯一其他无可争议的用途是防止通过指向编译器未意识到的同一内存的不同变量的不同变量对访问进行错误优化。但这可能只是无可争议的,因为人们没有在谈论它-我只看到其中一个提及。而且我认为C标准已经认识到“不同”的指针(例如指向函数的不同args)可能指向同一项目或附近的项目,并且已经指定编译器必须生成即使在这种情况下也可以工作的代码。但是,我无法在最新的标准(500页!)中快速找到此主题。

那么“使用3”也许根本不存在

因此,我的问题是:

在多核系统的可移植C代码中,“ volatile”是否可以保证任何东西?


编辑-更新

浏览最新标准后,答案似乎至少是非常有限的:
1.该标准针对特定类型“ volatile sig_atomic_t”反复指定特殊处理。但是该标准还说,在多线程程序中使用信号功能会导致不确定的行为。因此,该用例似乎仅限于单线程程序与其信号处理程序之间的通信。
2.该标准还为setjmp / longjmp指定了“ volatile”的明确含义。(在其他问题答案中给出了重要示例代码)。

因此,更精确的问题变成了:
除了(1)允许单线程程序从其信号处理程序接收信息之外,还是(2)允许setjmp,“ volatile”对于多核系统的便携式C代码是否有任何保证?代码以查看在setjmp和longjmp之间修改的变量?

这仍然是一个是/否问题。

如果为“是”,那么最好显示一个无错误的可移植代码示例,如果省略了“ volatile”,则该示例会出现错误。如果为“ no”,那么我认为对于多核目标,在这两种非常特殊的情况下,编译器可以随意忽略“ volatile”。

c multithreading portability volatile thread-safety

12
推荐指数
3
解决办法
309
查看次数

Emacs:是否可以将一个特定窗口设置为始终用作"其他窗口"?

有许多有用的emacs命令可以在"其他窗口"中执行操作(比如C-x C-b查看缓冲区列表,或C-h a查看可用命令,或许多其他命令).

我的问题:在一帧中使用一些精心安排的窗口,每个都显示特定的内容似乎不太好.

无论何时我使用其中一个"其他窗口"命令,它都会替换其他窗口的内容,其中(1)可能太窄而无法清楚地显示正在显示的信息,并且(2)可能需要手动"清理"然后,通过将其设置回正确的缓冲区.(最好不要在执行此操作时检查缓冲区列表,否则您将陷入另一个窗口!)

(即使从同一窗口发出命令,Emacs也不会总是使用相同的"其他窗口".例如,C-x C-b输出可能会进入一个"其他"窗口,同时C-h a在不同的"其他"窗口中显示其结果.同样,C-M-v有时会滚动与输出刚刚出现的窗口不同的"其他"窗口.)

我想要一种方法来解决或解决这个问题,例如:

  1. 我真的希望能够指定一个特定的窗口,始终用作该帧中任何窗口的"其他窗口".

  2. 如果失败了,也许有一种方法可以重新排列窗口顺序和/或使用不可见的窗口(如果存在的话)通过执行大量的幕后窗口改组来获得解决方案1的效果,可能需要额外的命令来在写入"其他窗口"的命令之前或之后输入.

  3. 如果失败了,我想要一个命令来撤消任何窗口中最近的缓冲区更改,因此无论使用什么窗口都会回到它在使用之前显示的内容.

(目前我使用workgroups.el并使用单独的工作组来检查文档,但这显然不是最理想的."更新"工作组没有实现解决方案3,因为它似乎只是在它是常规文件时才更改缓冲区.)

编辑:我看到这个问题与这个类似的问题非常相似,但这个问题没有得到它正在寻找的答案.由于理想的解决方案可能不存在,我也明确对解决方案感兴趣.

emacs

5
推荐指数
1
解决办法
285
查看次数

如何以编程方式提供“双前缀参数”?

在某些代码中,我想设置标记。

的文档set-mark-command说,

以 Cu Cu 作为前缀参数,无条件设置标记点所在的位置。

那我怎么set-mark-command用这种方式调用呢?

编辑:push-mark在这种特殊情况下,我认为我应该使用它。但是如何以编程方式提供双前缀参数的一般问题仍然存在。

emacs

4
推荐指数
1
解决办法
470
查看次数

标签 统计

emacs ×2

c ×1

multithreading ×1

portability ×1

thread-safety ×1

volatile ×1