Служит ли WaitForSingleObject барьером памяти?

Вчера вопрос о блокировке с двойной проверкой положил начало цепочке мыслей, из-за которых я не был уверен в простой ситуации. В следующем коде можно ли нажатьprintf «Больше не синхронизировано»? В этом простом примере значения, скорее всего, будут находиться в одной и той же строке кэша, поэтому я думаю, что это будет менее вероятно (при условии, что вероятность составляет> 0% для начала).

Если ответ «Нет, это невозможно», тогда мой дополнительный вопрос довольно предсказуем: почему бы и нет? Пока мои мысли не запутались и не обернулись вокруг многопоточного акселя вчера, я предполагал, что код будет безопасным. Но теперь мне интересно, что мешает устаревшему чтению из кэша для одной из переменныхpa или жеpb, И будет ли это иметь значение, еслиpa, pb указывает на простые глобальные целочисленные переменные, а не на память malloc? Предоставляет ли вызов WaitForSingleObject барьер памяти? Или указатели должны быть объявлены изменчивыми? Так много вопросов, так мало предложений.

Обновить: Я наконец-то нашел информацию, которая конкретно говорит о том, что функции, которые сигнализируют объектам синхронизации, действительно используютбарьеры памяти, Это должно было быть очевидно, но у меня были проблемы с поиском окончательного ответа. Так что я снова могу обмануть себя, поверив, что все это понимаю.

int i1 = 0;
int i2 = 0;
int reads = 0;
int done = 0;
int *pa = NULL;
int *pb = NULL;
HANDLE hSync = NULL;

DWORD WriteThread( LPVOID pvParam )
{
   while( !done )
      {
      WaitForSingleObject( hSync, INFINITE );
      (*pa)++;
      (*pb)++;
      ReleaseSemaphore( hSync, 1, NULL );
      }
   return 0;
}

DWORD ReadThread( LPVOID pvParam )
{
   while( !done )
      {
      WaitForSingleObject( hSync, INFINITE );
      if ( *pa != *pb )
         {
         printf( "No longer in sync: %d, %d\n", *pa, *pb );
         exit( 1 );
         }
      ReleaseSemaphore( hSync, 1, NULL );
      reads++;
      }
   return 0;
}

int main( int argc, char* argv[] )
{
   DWORD dwID;

   // malloc'd memory
   pa = (int*)malloc( sizeof( int ));
   pb = (int*)malloc( sizeof( int ));

   // Is a simple global variable different?
   //pa = &i1;
   //pb = &i2;

   *pa = 0;
   *pb = 0;

   hSync = CreateSemaphore( NULL, 1, 1, NULL );
   CreateThread( NULL, 0, WriteThread, NULL, 0, &dwID );
   CreateThread( NULL, 0, ReadThread, NULL, 0, &dwID );

   while ( *pa < 1000000 )
      Sleep( 1 );
   done = 1;

   return 0;
}

Ответы на вопрос(1)

Ваш ответ на вопрос