- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
假设我们有以下代码:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
void guarantee(bool cond, const char *msg) {
if (!cond) {
fprintf(stderr, "%s", msg);
exit(1);
}
}
bool do_shutdown = false; // Not volatile!
pthread_cond_t shutdown_cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t shutdown_cond_mutex = PTHREAD_MUTEX_INITIALIZER;
/* Called in Thread 1. Intended behavior is to block until
trigger_shutdown() is called. */
void wait_for_shutdown_signal() {
int res;
res = pthread_mutex_lock(&shutdown_cond_mutex);
guarantee(res == 0, "Could not lock shutdown cond mutex");
while (!do_shutdown) { // while loop guards against spurious wakeups
res = pthread_cond_wait(&shutdown_cond, &shutdown_cond_mutex);
guarantee(res == 0, "Could not wait for shutdown cond");
}
res = pthread_mutex_unlock(&shutdown_cond_mutex);
guarantee(res == 0, "Could not unlock shutdown cond mutex");
}
/* Called in Thread 2. */
void trigger_shutdown() {
int res;
res = pthread_mutex_lock(&shutdown_cond_mutex);
guarantee(res == 0, "Could not lock shutdown cond mutex");
do_shutdown = true;
res = pthread_cond_signal(&shutdown_cond);
guarantee(res == 0, "Could not signal shutdown cond");
res = pthread_mutex_unlock(&shutdown_cond_mutex);
guarantee(res == 0, "Could not unlock shutdown cond mutex");
}
符合标准的 C/C++ 编译器能否在调用 pthread_cond_wait()
时将 do_shutdown
的值缓存到寄存器中?如果不是,哪些标准/条款保证这一点?
编译器可以假设知道 pthread_cond_wait()
不会修改 do_shutdown
。这似乎不太可能,但我知道没有任何标准可以阻止它。
实际上,是否有任何 C/C++ 编译器在调用 pthread_cond_wait()
时将 do_shutdown
的值缓存在寄存器中?
编译器保证哪些函数调用不会缓存 do_shutdown
的值?很明显,如果函数是在外部声明的,并且编译器无法访问其定义,则它不能对其行为做出任何假设,因此无法证明它不会访问 do_shutdown
。如果编译器可以内联该函数并证明它不访问 do_shutdown
,那么即使在多线程设置中它也可以缓存 do_shutdown
吗?同一编译单元中的非内联函数怎么办?
最佳答案
当然,当前的 C 和 C++ 标准对这个主题只字不提。
据我所知,Posix 仍然避免正式定义并发模型(不过我可能已经过时了,在这种情况下,我的答案仅适用于早期的 Posix 版本)。因此,必须带着一点同情来阅读它所说的内容——它并没有精确地列出这方面的要求,但实现者应该“知道它的意思”并做一些让线程可用的事情。
当标准说互斥体“同步内存访问”时,实现必须假设这意味着在一个线程的锁下所做的更改将在其他线程的锁下可见。换句话说,同步操作必须(尽管还不够)包括一种或另一种内存屏障,内存屏障的必要行为是它必须假设全局变量可以改变。
Threads Cannot be Implemented as a Library涵盖了 pthreads 实际可用所需的一些特定问题,但在撰写本文时(2004 年)Posix 标准中并未明确说明。您的编译器编写者或为您的实现定义内存模型的人是否同意 Boehm 的“可用”含义,即允许程序员“令人信服地推理程序的正确性”,这一点变得非常重要。
请注意,Posix 不保证一致的内存缓存,因此如果您的实现反常地想要在代码的寄存器中缓存 do_something
,那么即使您将其标记为 volatile,它可能会在同步操作和读取 do_something
之间选择不弄脏 CPU 的本地缓存。因此,如果写入线程在具有自己的缓存的不同 CPU 上运行,即使那样您也可能看不到变化。
这就是(原因之一)为什么线程不能仅仅作为一个库来实现。这种仅从本地 CPU 缓存中获取 volatile 全局变量的优化在单线程 C 实现中是有效的[*],但会破坏多线程代码。因此,编译器需要“了解”线程,以及它们如何影响其他语言特性(例如 pthreads 之外的示例:在 Windows 上,缓存始终是一致的,Microsoft 阐明了它授予 volatile
在多线程代码中)。基本上,您必须假设,如果您的实现在提供 pthreads 函数方面遇到了麻烦,那么它也会在定义一个可行的内存模型时遇到麻烦,在该模型中锁实际上同步内存访问。
If the compiler can inline the function and prove it does not access do_shutdown, then can it cache do_shutdown even in a multithreaded setting? What about a non-inlined function in the same compilation unit?
对所有这些都是肯定的 - 如果对象是非 volatile 的,并且编译器可以证明该线程没有修改它(通过它的名称或通过别名指针),并且如果没有内存障碍发生,那么它可以重用以前的值。当然,有时会有其他特定于实现的条件阻止它。
[*] 前提是实现知道全局不位于某个“特殊”硬件地址,这要求读取始终通过缓存到主内存,以便查看影响该地址的任何硬件操作的结果。但是要在任何这样的位置放置一个全局变量,或者使用 DMA 或其他方式使其位置特殊,需要特定于实现的魔法。如果没有任何这样的魔法,原则上的实现有时可以知道这一点。
关于c++ - C/C++ 编译器能否通过 pthread 库调用合法地将变量缓存在寄存器中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4476446/
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: How to nest OR statements in JavaScript? 有没有办法做到这一点:
在 JavaScript 中有没有办法让一个变量总是等于一个变量?喜欢var1 = var2但是当var2更新,也是var1 . 例子 var var1 = document.getElementBy
我正在努力理解这代表什么 var1 = var2 == var3 我的猜测是这等同于: if (var2 == var3): var1 = var2 最佳答案 赋值 var1 = var2
这个问题已经有答案了: What does the PHP error message "Notice: Use of undefined constant" mean? (2 个回答) 已关闭 8
我在临时表中有几条记录,我想从每条记录中获取一个值并将其添加到一个变量中,例如 color | caption -------------------------------- re
如何将字符串转为变量(字符串变量--> $variable)? 或者用逗号分隔的变量列表然后转换为实际变量。 我有 2 个文件: 列名文件 行文件 我需要根据字符串匹配行文件中的整行,并根据列名文件命
我有一个我无法解决的基本 php 问题,我也想了解为什么! $upperValueCB = 10; $passNodeMatrixSource = 'CB'; $topValue= '$uppe
这可能吗? php $variable = $variable1 || $variable2? 如果 $variable1 为空则使用 $variable2 是否存在类似的东西? 最佳答案 PHP 5
在 Perl 5.20 中,for 循环似乎能够修改模块作用域的变量,但不能修改父作用域中的词法变量。 #!/usr/bin/env perl use strict; use warnings; ou
为什么这不起作用: var variable; variable = variable.concat(variable2); $('#lunk').append(variable) 我无法弄清楚这一点
根据我的理解,在32位机器上,指针的sizeof是32位(4字节),而在64位机器上,它是8字节。无论它们指向什么数据类型,它们都有固定的大小。我的计算机在 64 位上运行,但是当我打印包含 * 的大
例如: int a = 10; a += 1.5; 这运行得很完美,但是 a = a+1.5; 此作业表示类型不匹配:无法从 double 转换为 int。所以我的问题是:+= 运算符 和= 运算符
您好,我写了这个 MySQL 存储过程,但我一直收到这个语法错误 #1064 - You have an error in your SQL syntax; check the manual that
我试图在我的场景中显示特定的奖牌,这取决于你的高分是基于关卡的目标。 // Get Medal Colour if levelHighscore goalScore { sc
我必须维护相当古老的 Visual C++ 源代码的大型代码库。我发现代码如下: bIsOk = !!m_ptr->isOpen(some Parameters) bIsOk的数据类型是bool,is
我有一个从 MySQL 数据库中提取的动态产品列表。在 list 上有一个立即联系 按钮,我正在使用一个 jquery Modal 脚本,它会弹出一个表单。 我的问题是尝试将产品信息变量传递给该弹出窗
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: What is the difference between (type)value and type(va
jQuery Core Style Guidelines建议两种不同的方法来检查变量是否已定义。 全局变量:typeof variable === "undefined" 局部变量:variable
这个问题已经有答案了: 已关闭11 年前。 Possible Duplicate: “Variable” Variables in Javascript? 我想肯定有一种方法可以在 JavaScrip
在语句中使用多重赋值有什么优点或缺点吗?在简单的例子中 var1 = var2 = true; 赋值是从右到左的(我相信 C# 中的所有赋值都是如此,而且可能是 Java,尽管我没有检查后者)。但是,
我是一名优秀的程序员,十分优秀!