我已经看到了::std::thread等等的文章::std::forward,但我没有看过任何好文章::std::atomic.当然,还有标准提案文件,但我还没有看到任何想要使用该设施的人的良好文档.
有没有?我在哪里可以找到它?
我读到C++ 11引入了属性的概念,例如[[noreturn]],它表明函数不会返回给调用者.
[[noreturn]] void fun()
{
throw std::string("Error!!!");
}
void func()
{
fun();
}
void aTempFunc()
{
try
{
func();
}
catch (std::string &e)
{
std::cout << e << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
通过查看示例,读者可以理解该函数抛出异常并且不会将调用返回给func函数.我有点困惑,了解什么是C++属性以及为什么需要它?程序员如何才能真正利用这些属性?
有人可以详细解释.如果我对属性的理解是错误的,请纠正我.谢谢.
我发现了一些问题(比如这个)问什么[[carries_dependency]]是,这不是我在这里问的。
我想知道你什么时候不应该使用它,因为我读过的所有答案都让人觉得你可以把这段代码贴在任何地方,而且你会神奇地得到相等或更快的代码。一个评论说代码可以相等或更慢,但海报没有详细说明。
我想在任何函数返回或参数上使用 this 的合适位置是指针或引用,并且将在调用线程内传递或返回,并且不应在回调或线程入口点上使用它。
有人可以评论我的理解并详细说明一般的主题,何时以及何时不使用它?
c++ multithreading memory-model carries-dependency stdatomic
我读过有关携带依赖关系和依赖关系排序之前,在其定义中使用一个5.1.2.4(p16):
在以下情况下,评估
A在评估之前是依赖顺序的B:—
A对原子对象执行释放操作M,并在另一个线程中B执行消耗操作M并读取以 为首的释放序列中的任何副作用写入的值A,或— 对于某些求值
X,A之前是依存顺序X并X带有对 的依存关系B。
所以我试图制作一个可能有用的例子。就这个:
static _Atomic int i;
void *produce(void *ptr){
int int_value = *((int *) ptr);
atomic_store_explicit(&i, int_value, memory_order_release);
return NULL;
}
void *consume(void *ignored){
int int_value = atomic_load_explicit(&i, memory_order_consume);
int new_int_value = int_value + 42;
printf("Consumed = %d\n", new_int_value);
}
int main(int …Run Code Online (Sandbox Code Playgroud) 我在这篇SO帖子中阅读了 [[carries_dependency]] 。
但我无法理解的是接受的答案中的以下句子:
“特别是,如果将使用 memory_order_consume 读取的值传递给函数,然后没有 [[carries_dependency]],那么编译器可能必须发出内存栅栏指令以保证支持适当的内存排序语义。如果参数用 [[carries_dependency]] 注释,那么编译器可以假设函数体将正确携带依赖项,并且可能不再需要此围栏。
类似地,如果一个函数返回一个加载了 memory_order_consume 的值,或者从这样的值派生,那么如果没有 [[carries_dependency]],编译器可能需要插入一个栅栏指令来保证适当的内存排序语义得到支持。有了 [[carries_dependency]] 注释,这个围栏可能不再是必要的,因为调用者现在负责维护依赖树。”
让我们一步一步来:
“如果将使用 memory_order_consume 读取的值传递给函数,然后没有 [[carries_dependency]],那么编译器可能必须发出内存栅栏指令,以确保支持适当的内存排序语义。”
因此,对于释放-消耗内存模型中的原子变量,当原子变量作为参数传递给函数时,编译器将引入栅栏硬件指令,以便它始终具有提供给函数的原子变量的最新和更新值。
下一个 -
“如果参数用 [[carries_dependency]] 注释,那么编译器可以假设函数体将正确携带依赖项,并且可能不再需要这个围栏。”
这让我很困惑 - 原子变量值已经被消耗了,然后函数携带了什么依赖?
相似地 -
“如果一个函数返回一个加载了 memory_order_consume 的值,或者从这样的值派生,那么如果没有 [[carries_dependency]],编译器可能需要插入一个栅栏指令来保证适当的内存排序语义得到支持。使用 [[ Carry_dependency]] 注释,这个围栏可能不再是必要的,因为调用者现在负责维护依赖树。”
从这个例子中,它不清楚它试图说明携带依赖的意义是什么?