- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在实现一个单生产者单消费者队列,其中一个线程等待全局队列被另一个线程填充,如下所示:
while (queue.head == queue.tail);
当我编译程序时将 gcc -O0,它运行良好。但是用gcc -O1编译的时候,死循环发生了。然后我查看汇编代码,发现后一个版本只检查了一次(queue.head == queue.tail),如果不正确,则跳到一个死循环,不再检查。
我还尝试将队列声明为易变的,但没有成功。如何让 gcc 意识到队列在线程之间共享并停止这样的优化?非常感谢。
附言
1 在单线程程序中,这样优化是可以的。但是在我的程序中queue.tail可以被另一个线程修改。
2 我的队列是这样声明的:
typedef struct {
struct my_data data[MAX_QUEUE_LEN];
int head;
int tail;
} my_queue_t;
volatile my_queue_t queue;
3 我也曾尝试将 head 和 tail(但不是整个结构)声明为 volatile,但没有成功。但是在我声明 queue、head、tail 都为 volatile 之后,它就起作用了。那么是否应该像这样向所有相关变量声明 volatile?
最佳答案
我编译了以下代码:
struct my_data {
int x;
};
typedef struct {
struct my_data data[5];
int head;
int tail;
} my_queue_t;
volatile my_queue_t queue;
int main() {
while (queue.head == queue.tail);
}
与:
g++ -S -c -O1 th.cpp
这(对于 while 循环)产生了以下输出:
movl $_queue+20, %edx
movl $_queue+24, %eax
L2:
movl (%edx), %ebx
movl (%eax), %ecx
cmpl %ecx, %ebx
je L2
在循环中加载和测试头部和尾部的位置。你能发布你正在发射的汇编程序吗?
编辑:在结构声明中将 head 和 tail 设为 volatile,而不是将 struct 实例声明为 volatile,结果是相同的代码。
关于c - gcc 将忙等待优化为死循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/991212/
根据https://developers.google.com/google-apps/calendar/v3/reference/freebusy/query处的文档要执行空闲/忙碌查询,您必须在正
我在启动 Apache 后使用 XAMPP 1.7.7 我收到此警报: Busy... Apache started [Port 80] 我已经打开了 httpd.conf 文件,并将端口号更改为 8
我有端口问题。 每当我启动 Apache 时,它都会给我这个错误: Busy - Apache Started [port 80] 当我启动 Mysql 时出现以下错误: Busy - ERROR
当我运行我的代码时,我总是得到后台工作人员很忙。有帮助吗? struct FtpSetting { public string Server { get; set
在我们的 Android 和 iOS MVVMCross 应用程序中,我们偶尔会遇到 SQLiteException: busy 异常。 给定下面的代码,我们有几个存储库,每个存储库都构造一个下面的实
每次运行解决方案(20 projs)时,我都会收到此错误。我尝试禁用 UI 选项、resharper、删除未使用的扩展等,但仍然无法通过此错误。 我使用的是 VS 2015 Update 2 Ente
我正在使用这个插件 https://github.com/mozilla/rust-android-gradle ,这需要我添加 tasks.whenTaskAdded { task -> i
我是一名优秀的程序员,十分优秀!