我想知道为什么没有编译器准备将相同值的连续写入合并到单个原子变量,例如:
#include <atomic>
std::atomic<int> y(0);
void f() {
auto order = std::memory_order_relaxed;
y.store(1, order);
y.store(1, order);
y.store(1, order);
}
Run Code Online (Sandbox Code Playgroud)
我尝试过的每个编译器都会发出三次上面的编写.什么合法的,无种族的观察者可以看到上述代码与具有单次写入的优化版本之间的差异(即,不是"假设"规则适用)?
如果变量是易变的,那么显然不适用优化.在我的情况下有什么阻止它?
这是编译器资源管理器中的代码.
我从许多来源读到这个volatile关键字 在多线程场景中没有帮助 .但是,这个断言一直受到接受指针的原子操作函数的挑战.volatile
例如,在Mac OS X上,我们有OSAtomic函数系列:
SInt32 OSIncrementAtomic(volatile SInt32 *address);
SInt32 OSDrecrementAtomic(volatile SInt32 *address);
SInt32 OSAddAtomic(SInt32 amount, volatile SInt32 *address);
// ...
Run Code Online (Sandbox Code Playgroud)
似乎volatileWindows 上的关键字类似于Interlocked操作:
LONG __cdecl InterlockedIncrement(__inout LONG volatile *Addend);
LONG __cdecl InterlockedDecrement(__inout LONG volatile *Addend);
Run Code Online (Sandbox Code Playgroud)
似乎在C++ 11中,原子类型具有volatile修饰符的方法,它必须以某种方式表示volatile关键字与原子性有某种关系.
那么,我错过了什么?为什么操作系统供应商和标准库设计者坚持使用volatile关键字进行线程化,如果它没用?
我在2001年发现了一篇关于Dobbs博士的文章:volatile - 多线程程序员最好的朋友.我总是发现'volatile'有点无用 - 至少作为变量的限定符 - 因为对线程之间共享的变量的访问总是会经历某种类型的库层.
尽管如此,将类实例和方法标记为"易变"以表明文章中提供的线程安全程度似乎非常引人注目.
为了快速总结一下这篇文章,核心思想是可以声明一个这样的类:
struct SomeObject {
void SingleThreadedMethod();
void Method();
void Method() volatile;
};
Run Code Online (Sandbox Code Playgroud)
然后,类的实例,如下所示:
// An object that will only be accessed from a single thread.
SomeObject singleThreaded;
// An objecect that will be accessed from multiple threads.
volatile SomeObject sharedObject;
sharedObject.SingleThreadedMethod(); //this will be an compile error
sharedObject.Method(); // will call the volatile overload of Method
singleThreaded.Method(); // would call the non volatile overload of Method.
Run Code Online (Sandbox Code Playgroud)
想法是实现像"Method()volatile"这样的方法:
void SomeObject::Method() volatile …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用C++ 11中的std :: thread.如果可以在执行其某个函数成员的类中使用std :: thread,我找不到任何地方.考虑下面的例子......在我的尝试(下面)中,函数是run().
我使用-std = c ++ 0x标志用gcc-4.4编译.
#ifndef RUNNABLE_H
#define RUNNABLE_H
#include <thread>
class Runnable
{
public:
Runnable() : m_stop(false) {m_thread = std::thread(Runnable::run,this); }
virtual ~Runnable() { stop(); }
void stop() { m_stop = false; m_thread.join(); }
protected:
virtual void run() = 0;
bool m_stop;
private:
std::thread m_thread;
};
class myThread : public Runnable{
protected:
void run() { while(!m_stop){ /* do something... */ }; }
};
#endif // RUNNABLE_H
Run Code Online (Sandbox Code Playgroud)
我收到这个错误和其他人:(有和没有$ this相同的错误)
Runnable.h|9|error: no matching function for …Run Code Online (Sandbox Code Playgroud) InterlockedIncrement和其他Interlocked操作将其参数声明为volatile.为什么?这是什么意图和影响?