while循环与空身体检查挥发性整数 – 这是什么意思?
我正在看一个有以下几行的C ++类:
while( x > y ); return x - y;   x和y是volatile inttypes的成员variables。 我不明白这个构造。 
我在这里find代码存根: https : //gist.github.com/r-lyeh/cc50bbed16759a99a226 。 我想这不能保证是正确的,甚至工作。
 由于x和y已经被声明为volatile,程序员期望他们会从程序之外改变。 
在这种情况下,你的代码将保持在循环中
  while(x>y); 
 并且在值从外部改变之后将返回值xy ,使得x <= y 。 当你告诉我们更多关于你的代码和你看到它的地方之后,这个写法的确切原因是可以猜到的。 在这种情况下, while循环是一些其他事件发生的等待技巧。 
它似乎
 while( x > y ); 
 是一个纺纱循环 。 它不会停止,直到x <= y 。 由于x和y是volatile ,它们可能会在这个例程之外被改变。 所以,一旦x <= y成立, x - y将被返回。 这个技巧是用来等待一些事件的。 
更新
根据您添加的要点 ,似乎想法是实现线程安全的无锁循环缓冲区。 是的,实施是不正确的。 例如,原始的代码片段是
 unsigned count() const { while( tail > head ); return head - tail; } 
 即使tail变小或等于head ,也不能保证head - tail返回正数。 调度程序可能会在while循环之后立即将执行切换到另一个线程,并且该线程可能会更改head值。 无论如何,还有很多其他的问题涉及如何读写共享内存工作(内存重新sorting等),所以只是忽略这个代码。 
 其他的回复已经详细指出了这个指令的作用,但是要回顾一下,由于y (或者在链接的例子中是head )被声明为从不同的线程对该variables进行的volatile变化将导致while循环完成一次病情已经得到满足。 
但是,即使链接的代码示例非常短,这也是如何不编写代码的完美例子。
首先是线路
 while( tail > head ); 
会浪费大量的CPU周期,几乎locking一个核心,直到满足条件。
随着我们的进展,代码变得更好。
 buffer[head++ % N] = item; 
  感谢JAB指出我错误地在这里预增。  更正了影响。 由于没有lock或mutex我们显然将不得不承担最坏的情况。 线程将在分配值中的值和在执行head++之前切换。 墨菲将再次调用包含这个语句的函数,在同一个head位置分配item的值。 之后, head增加。 现在我们切换回第一个线程并再次递增。 所以,而不是 
 buffer[original_value_of_head+1] = item_from_thread1; buffer[original_value_of_head+2] = item_from_thread2; 
我们结束了
 buffer[original_value_of_head+1] = item_from_thread2; buffer[original_value_of_head+2] = whatever_was_there_previously; 
 你可能会在客户端用这种蹩脚的编码离开,只有很less的线程,但在服务器端,这只能被认为是一个定时炸弹。 请使用同步结构,例如lock s或mutex es。 
而且,只是为了完整性,行
 while( tail > head ); 
 在方法pop_back()应该是 
 while( tail >= head ); 
除非你想能够popup一个多于你实际推入的元素(甚至在推入任何东西之前popup一个元素)。
对不起,写了一个基本归结为一个长长的咆哮,但如果这只保留一个人复制和粘贴该淫秽的代码,这是值得的。
 更新:以为我不妨给一个例子,像while(x>y); 其实是非常有意义的。 其实你曾经在“古老的”时代经常看到这样的代码。  咳嗽 DOS。 虽然在线程中使用过。 主要是作为一个后备的情况下注册一个中断挂钩是不可能的(你的孩子可能会把它翻译为“不可能注册一个事件处理程序”)。 
 startAsynchronousDeviceOperation(..); 
 这可能几乎是任何东西,例如告诉硬盘通过DMA读取数据,或告诉声卡通过DMAlogging,甚至可能调用不同处理器(如GPU)上的function。 通常通过类似outb(2) 。 
 while(byteswritten==0); // or while (status!=DONE); 
如果与设备的唯一通信通道是共享内存,那就这样吧。 不过,期望看到现在的设备驱动程序和微控制器以外的代码。 显然,假定规格说明了内存位置是写入的最后一个位置。
  volatile关键字旨在防止某些优化。 在这种情况下,如果没有关键字,编译器可能会将while循环展开成具体的指令序列,这些指令显然会破坏现实,因为这些值可能会在外部进行修改。 
想象一下:
 int i = 2; while (i-- > 0) printf("%d", i); 
 大多数编译器都会看这个,只是简单地生成两个printf调用 – 添加volatile关键字会导致产生CPU指令,调用计数器设置为2,并在每次迭代后检查值。 
例如,
 volatile int i = 2; this_function_runs_on_another_process_and_modifies_the_value(&i); while(i-- > 0) printf("%d", i);