c ++ 0x многопоточность видимости памяти без атомарных операций - PullRequest
0 голосов
/ 09 сентября 2018

Общая схема синхронизации данных между потоками (помимо использования спин-блокировки) с атомарностью выглядит следующим образом:

int data;
std::atomic<bool> ready;

void thread1()
{
   data = 123;
   ready.store(true, std::memory_order_release);
}
void thread2()
{
   while(!ready.load(std::memory_order_acquire));
   int theData = data;
   assert(theData == 123);
}

или лучше:

void thread2()
{
   while(!ready.load(std::memory_order_relaxed));
   std::atomic_thread_fence(std::memory_order_acquire);
   int theData = data;
   assert(theData == 123);
}

Флаг «готовности» используется для 1) определения того, когда данные действительно готовы, и 2) для отношения «случайный случай до».

Но если я каким-то образом знаю (потенциально не используя атомарность c ++), что данные будут готовы, когда я их прочитаю, то могу ли я опустить этот тип флага?

Могу ли я использовать это:

int data = 0;
void thread1()
{
   sleep(1000);
   data = 123;
   std::atomic_thread_fence(some_order);
}
void thread2()
{
   sleep(2000);
   std::atomic_thread_fence(some_order);
   int theData = data;
   assert(theData == 123);
}

или

std::atomic<int> atmData(0);
void thread1()
{
   sleep(1000);
   atmData.store(123, some_order);
}
void thread2()
{
   sleep(2000);
   int theData = atmData.load(some_order);
   assert(theData == 123);
}

А если так, то каким может быть some_order? Я не уверен, что это было бы возможно, так как даже с std::memory_order_seq_cst операции заказа все еще могут видеть устаревшее значение. С другой стороны, для работы std::atomic_thread_fence() требуется атомарная операция (согласно https://en.cppreference.com/w/cpp/atomic/atomic_thread_fence).

РЕДАКТИРОВАТЬ: Это довольно теоретический вопрос о том, как синхронизация памяти работает в C ++, а не о том, как я должен использовать механизмы ожидания или знать, когда безопасно получить доступ к данным.

...