草庐IT

具有非平凡类型的 C++ 原子?

阅读boost::atomic上的文档和std::atomic让我感到困惑的是atomic是否接口(interface)应该支持非平凡类型?也就是说,给定一个只能通过将读/写包含在一个完整的互斥锁中来写/读的(值)类型,因为它有一个非平凡的复制构造函数/赋值运算符,这应该是由std::atomic支持(因为boost明确指出它是UB)。我应该提供特化吗docs谈论我自己的非平凡类型?注意:我之所以想到这个是因为我有一个跨线程回调对象boost::functionsimpleFn;需要自动设置/重置。拥有一个单独的互斥锁/关键部分,或者甚至将两者都包装在一个类似原子的辅助类型中,使用简单

c++ 11 std::atomic_flag,我使用正确吗?

我有一个简单的bool值,需要以线程安全的方式进行测试和设置。如果一个线程已经在工作,我希望第二个线程退出。如果我明白std::atomic_flag正确,这应该可以正常工作。但是,我不确定我是否正确理解了std::atomic_flag:)我似乎无法在网上找到很多简单的示例,除了这个自旋锁示例://myclass.cpp#usingnamespace//anonymousnamespace{std::atomic_flag_my_flag=ATOMIC_FLAG_INIT;}//nsmyclass::do_something(){if(!::_my_flag.test_and_set

c++ - CUDA、互斥量和 atomicCAS()

最近开始在CUDA上开发,遇到了atomicCAS()的问题。要在设备代码中对内存进行一些操作,我必须创建一个互斥量,以便只有一个线程可以在代码的关键部分使用内存。下面的设备代码在1个block和多个线程上运行。__global__voidcudaKernelGenerateRandomGraph(...,int*mutex){inti=threadIdx.x;...do{atomicCAS(mutex,0,1+i);}while(*mutex!=i+1);//criticalsection//dosomemanipulationswithobjectsindevicememory*m

c++ - 为什么 std::atomic 的 compare_exchange 会引用期望值?

std::atomic::compare_exchange_*的原因是什么?通过引用获取期望值,而不是通过值获取期望值? 最佳答案 如果操作失败,compare_exchange_*会将expected更改为实际值。它使循环更简单一些。 关于c++-为什么std::atomic的compare_exchange会引用期望值?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1998

c++ - 为什么 std::atomic 在 Visual C++ 中不是简单的类型?

Folly库需要std::atomic应该是一个普通的类型。这适用于gcc和clang,但对于VisualC++即使对于std::atomic也是如此。.为什么std::is_trivial返回false?#include#includestatic_assert(std::is_trivial>::value,"std::atomicnottrivial"); 最佳答案 std::atomic曾经是微不足道的(这需要TriviallyCopyable),但现在不再是了。参见thisanswer以获得有关如何以及为何发生变化的详尽解

c++ - 为什么对象的初始化会调用复制构造函数?

考虑以下最小工作示例:#includeintmain(){::std::atomica=false;}atomic的Copyctor和copyassignment都被显式删除。但是,这应该调用ctortakingexactlyabool.g++和clang++都提示这一行试图调用atomic的复制构造函数:$g++-std=c++1za.cppa.cpp:Infunction‘intmain()’:a.cpp:4:27:error:useofdeletedfunction‘std::atomic::atomic(conststd::atomic&)’::std::atomica=fal

c++ - 为什么 std::atomic 中的所有成员函数都带有和不带有 volatile?

我注意到std::atomic的大多数成员函数类型被声明了两次,一次是用volatile修饰符,一次没有(example))。我检查了G++标准库实现的源代码,发现它们都是完全相同的,例如,boolload(memory_order__m=memory_order_seq_cst)constnoexcept{return_M_base.load(__m);}boolload(memory_order__m=memory_order_seq_cst)constvolatilenoexcept{return_M_base.load(__m);}我找不到任何volatile的例子变体的行为不

c++ - shared_ptr 原子函数采用指针而不是引用的基本原理

如你所见here,shared_ptr作为指针而不是引用传递。还要注意Allthesefunctionsinvokeundefinedbehaviorifpisanullpointer.那么为什么是指针呢?我认为在C++中,应该优先使用引用,除非有特定的原因需要使用指针。 最佳答案 templateboolatomic_is_lock_free(conststd::shared_ptr*p);接受一个指向智能指针的指针,因为这是更通用的atomic_is_lock_free的特例:templateboolatomic_is_lock

c++ - 使用 OpenMP 原子操作获取和添加

我正在使用OpenMP并且需要使用获取和添加操作。但是,OpenMP不提供适当的指令/调用。我想保留最大的可移植性,因此我不想依赖编译器内部函数。相反,我正在寻找一种方法来利用OpenMP的原子操作来实现这一点,但我已经走到了死胡同。这甚至可以做到吗?注意,下面的代码几乎做了我想要的:#pragmaompatomicx+=a几乎——但不完全是,因为我真的需要x的旧值。fetch_and_add应定义为产生与以下相同的结果(仅非锁定):templateTfetch_and_add(volatileT&value,Tincrement){Told;#pragmaompcritical{ol

c++ - 防止 std::atomic 溢出

我有一个原子计数器(std::atomiccount),它向多个线程处理顺序递增的值。uint32_tmy_val=++count;在我得到my_val之前我想确保增量不会溢出(即:回到0)if(count==std::numeric_limits::max())throwstd::runtime_error("countoverflow");我认为这是一个天真的检查,因为如果在递增计数器之前由两个线程执行检查,则第二个要递增的线程将返回0if(count==std::numeric_limits::max())//if2threadsexecutethisthrowstd::runt