虽然循环与空体检查易失性整数 - 这意味着什么
While loop with empty body checking volatile ints - what does this mean?
我正在查看一个具有以下行的C++类:
while( x > y );
return x - y;
x
和 y
是 volatile int
类型的成员变量。我不明白这个结构。
我在这里找到了代码存根:https://gist.github.com/r-lyeh/cc50bbed16759a99a226。我想它不能保证正确甚至有效。
由于 x
和 y
已被声明为易失性,程序员希望它们将从程序外部更改。
在这种情况下,您的代码将保留在循环中
while(x>y);
并将在从外部更改值后返回值x-y
,以便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
值。无论如何,还有很多与读取和写入共享内存的工作方式(内存重新排序等(相关的其他问题,因此请忽略此代码。
其他回复已经详细指出了该指令的作用,但只是回顾一下,由于y
(或链接示例中的head
(被声明为 volatile
从不同线程对该变量所做的更改将导致while
循环在满足条件后完成。
但是,即使链接的代码示例非常短,它也是一个非常完美的示例,说明如何不编写代码。
首先是生产线
while( tail > head );
将浪费大量的 CPU 周期,几乎锁定一个内核,直到满足条件。
随着我们的发展,代码会变得更好。
buffer[head++ % N] = item;
感谢 JAB 指出我在这里错误地将后期与预增量联系起来。更正了含义。由于没有lock
或mutex
,我们显然将不得不假设最坏的情况。线程将在 item
中分配值之后和执行head++
之前切换。然后,Murphy 将再次调用包含此语句的函数,在同一head
位置分配 item
的值。之后head
递增。现在我们切换回第一个线程并再次递增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;
您可能会在线程很少的客户端上摆脱像这样的草率编码,但在服务器端,这只能被视为定时炸弹。请改用同步结构,例如 lock
s 或 mutex
es。
好吧,只是为了完整起见,这条线
while( tail > head );
在方法中pop_back()
应该是
while( tail >= head );
除非您希望能够弹出比实际推入的元素多一个元素(甚至在推入任何元素之前弹出一个元素(。
很抱歉写了基本上归结为冗长的咆哮的内容,但如果这只阻止一个人复制和粘贴淫秽代码,那么值得一试。
更新:我想我不妨举一个例子,像while(x>y);
这样的代码实际上非常有意义。 实际上,在"美好的旧"时代,您经常看到这样的代码。咳嗽DOS。不过没有在线程上下文中使用。主要作为无法注册中断钩子的回退(您的孩子可能会将其翻译为"无法注册事件处理程序"(。
startAsynchronousDeviceOperation(..);
这可能是几乎任何东西,例如告诉hardisk通过DMA读取数据,或者告诉声卡通过DMA录制,甚至可能调用不同处理器(如GPU(上的函数。通常通过类似 outb(2)
.
while(byteswritten==0); // or while (status!=DONE);
如果与设备的唯一通信通道是共享内存,那就这样吧。不过,现在不会期望在设备驱动程序和微控制器之外看到这样的代码。显然,假设规范声明内存位置是最后一个写入的位置。
volatile
关键字旨在防止某些优化。在这种情况下,如果没有关键字,编译器可以将您的while
循环展开为具体的指令序列,这些指令显然会在现实中中断,因为可以在外部修改值。
想象一下以下内容:
int i = 2;
while (i-- > 0) printf("%d", i);
大多数编译器会查看这一点并简单地生成两个对printf
的调用 - 添加 volatile
关键字将导致它生成调用设置为 2 的计数器并在每次迭代后检查值的 CPU 指令。
例如
volatile int i = 2;
this_function_runs_on_another_process_and_modifies_the_value(&i);
while(i-- > 0) printf("%d", i);
- 如何反转整数参数包
- enum是C++中的宏变量还是整数变量
- 努力将整数转换为链表。不知道我在这里做错了什么
- 整数不会重复超过随机数
- 在C++中手动调整数组大小
- 检查输入是否不是整数或数字
- C++使用整数的压缩数组初始化对象
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 如何只允许用户输入正整数
- 如何在c++中从文本文件中逐行读取整数
- C++:如何循环通过向量中的整数元素
- 我可以信任表示整数的浮点或双精度来保持精度吗
- 序列化,没有库的整数,得到奇怪的结果
- 在一定长度后从数组中打印时缺少整数
- std::当在256字节边界上写入整数时,流的奇怪行为
- 内联程序集printf将整数解释为地址
- 是否基于数组B整数打印数组A中的整数
- 虽然循环与空体检查易失性整数 - 这意味着什么