byte[0] = 0x51;
byte[0] = 0x52;
byte[0] = 0x53;


int a = 1;
b = a;
c = 2;


#include <iostream>
#include <atomic>

using namespace std;

atomic<int> b {0};
atomic<int> c {0};

int a = 1;
b = a;
c = 2;
return 0;
}

while(c != 2) {}
cout << b << "," << c << endl;
return 0;
}

int main(int argc, char *argv[]) {
t0.join();
t1.join();

return 0;
}


volatile

C++ 11的定义：

Every access (read or write operation, member function call, etc.) made through a glvalue expression of volatile-qualified type is treated as a visible side-effect for the purposes of optimization (that is, within a single thread of execution, volatile accesses cannot be optimized out or reordered with another visible side effect that is sequenced-before or sequenced-after the volatile access. This makes volatile objects suitable for communication with a signal handler, but not with another thread of execution, see std::memory_order).

Side effect: Accessing an object designated by a volatile glvalue, modifying an object, calling a library I/O function, or calling a function that does any of those operations are all side effects, which are changes in the state of the execution environment.

Sequence point: A sequence point is a point in the execution sequence where all side effects from the previous evaluations in the sequence are complete, and no side effects of the subsequent evaluations started.

/** The work this thread is doing. */
IQueuedWork* volatile QueuedWork;

/**
* The real thread entry point. It waits for work events to be queued. Once
* an event is queued, it executes it and goes back to waiting.
*/
virtual uint32 Run() override
{
while (!TimeToDie)
{
// This will force sending the stats packet from the previous frame.
// We need to wait for shorter amount of time
bool bContinueWaiting = true;
while( bContinueWaiting )
{
// Wait for some work to do
bContinueWaiting = !DoWorkEvent->Wait( 10 );
}

IQueuedWork* LocalQueuedWork = QueuedWork;
QueuedWork = nullptr;
FPlatformMisc::MemoryBarrier();
check(LocalQueuedWork || TimeToDie); // well you woke me up, where is the job or termination request?
while (LocalQueuedWork)
{
// Tell the object to do the work
// Let the object cleanup before we remove our ref to it
}
}
return 0;
}

/**
* Tells the thread there is work to be done. Upon completion, the thread
* is responsible for adding itself back into the available pool.
*
* @param InQueuedWork The queued work to perform
*/
void DoWork(IQueuedWork* InQueuedWork)
{

check(QueuedWork == nullptr && "Can't do more than one task at a time");
// Tell the thread the work to be done
QueuedWork = InQueuedWork;
FPlatformMisc::MemoryBarrier();
// Tell the thread to wake up and do its job
DoWorkEvent->Trigger();
}


Android和Linux:

FORCEINLINE static void MemoryBarrier()
{
__sync_synchronize();
}


iOS和Mac：

FORCEINLINE static void MemoryBarrier()
{
OSMemoryBarrier();
}


Windows：

void FGenericPlatformMisc::MemoryBarrier()
{
}