簡體   English   中英

WaitForSingleObject是否可用作內存屏障?

[英]Does WaitForSingleObject Serve as a Memory Barrier?

昨天關於雙重檢查鎖定的一個問題引發了一連串的想法,讓我不確定一個簡單的情況。 在下面的代碼中,是否可以點擊“不再同步”的printf 在這個簡單的例子中,值可能在同一個緩存行上,所以我認為它不太可能(假設開始時可能性> 0%)。

如果答案是“不,這是不可能的。”,那么我的后續問題是,相當可預見的:為什么不呢? 直到昨天我的想法糾結並纏繞在多線程軸上,我認為代碼是安全的。 但是現在我想知道是什么阻止了從緩存中讀取一個變量papb的過時。 如果pa, pb指向簡單的全局整數變量而不是malloc內存pa, pb那會不會有問題? WaitForSingleObject調用是否提供內存屏障? 或者指針是否應聲明為volatile? 這么多問題,句子很少。

更新 :我最終找到的信息明確指出,信號同步對象的函數確實使用了內存屏障 應該是顯而易見的,但我找不到明確的答案。 所以我可以再次欺騙自己相信我理解這一切。

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

內存所在的位置並不重要,如果它都是關於緩存一致性的,那么聲明變量volatile將無法解決它。 易失性的語義對於線程安全既不必要也不充分; 不要用它!

在C / C ++級別,pa和pb可以緩存在寄存器中,但在任何函數調用之后它們將被視為過時。 在CPU級別,所有等待函數都使用障礙來確保一切按預期工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM