【问题标题】:Does WaitForSingleObject Serve as a Memory Barrier?WaitForSingleObject 是否用作内存屏障?
【发布时间】:2010-12-30 09:14:13
【问题描述】:

昨天一个关于双重检查锁定的问题引发了一连串的想法,让我不确定一个简单的情况。在下面的代码中,是否可以点击“不再同步”的printf?在这个简单的例子中,这些值可能在同一个缓存行上,所以我认为它不太可能(假设开始的可能性 > 0%)。

如果答案是“不,这是不可能的”,那么我的后续问题是可以预见的:为什么不呢?直到昨天我把我的想法纠缠在多线程轴上,我认为代码是安全的。但现在我想知道是什么阻止了从缓存中对变量pa 或pb 之一进行过时的读取。如果 pa, pb 指向简单的全局整数变量而不是 malloc 的内存,这有关系吗? WaitForSingleObject 调用是否提供内存屏障?还是应该将指针声明为 volatile?这么多问题,这么少的句子。

更新:我终于找到了明确说明信号同步对象的函数确实使用memory barriers 的信息。这应该很明显,但我很难找到明确的答案。所以我可以再一次自欺欺人地相信我明白这一切。

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;
}

【问题讨论】:

    标签: c multithreading winapi memory


    【解决方案1】:

    内存在哪里并不重要,如果它只是关于缓存一致性,那么声明变量 volatile 将无济于事。 Volatile 的语义对于线程安全来说既非必要也不充分;不要使用它!

    在 C/C++ 级别,pa 和 pb 可以缓存在寄存器中,但在任何函数调用之后它们都将被认为是陈旧的。在 CPU 级别,所有等待函数都使用屏障来确保一切按预期工作。

    【讨论】:

    • 感谢您提供的信息。您是否碰巧知道讨论等待功能和内存屏障的链接。这就是我一直在寻找但没有看到的东西。很可能我只是瞎了眼,错过了一些明显的东西。
    • 你不是瞎子;在网上很难找到相关信息。 MSDN 在msdn.microsoft.com/en-us/library/ms686355%28VS.85%29.aspx 上提供了相当不错的概述。
    猜你喜欢
    • 2014-05-24
    • 2010-12-07
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 2011-10-12
    • 2014-12-05
    • 2013-01-18
    • 1970-01-01
    相关资源
    最近更新 更多