Windows 原子Interlocked单向链式栈

来源:互联网 发布:淘宝客服经典话术大全 编辑:程序博客网 时间:2024/06/07 20:31

SLists使用了无锁算法来保证原子同步,以提升系统性能,避免了诸如优先级挂和互锁的问题。

注意:所有的链表项必须对齐到MEMORY_ALLOCATION_ALIGNMENT。否则会出现奇葩的错误。

(PS:看英文MSDN的API解释,我感觉这是从前插又从前取,是个栈的样子。)

InitializeSListHead创建一个空栈

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. void WINAPI InitializeSListHead(  
  2.   __inout  PSLIST_HEADER ListHead//SLIST_HEADER类型的链头,供系统使用。  
  3. );  
InterlockedFlushSList清空(感觉这个返回值没什么用的样子,难道可以先全部得到,然后根据链表中元素数量再一个一个地用?求解释。)

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. PSLIST_ENTRY WINAPI InterlockedFlushSList(  
  2.   __inout  PSLIST_HEADER ListHead//创建空栈时用的那个链头  
  3. );  
InterlockedPushEntrySList在头添加(区别于从尾部添加),返回值为之前的第一项,如果之前为空链,则返回NULL。
[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. PSLIST_ENTRY WINAPI InterlockedPushEntrySList(  
  2.   __inout  PSLIST_HEADER ListHead,//创建空栈时用的那个链头  
  3.   __inout  PSLIST_ENTRY ListEntry//插入项  
  4. );  
InterlockedPopEntrySList在头取出(区别于从尾部取出),返回值就是取的那个项的指针,如果之前为空链,则返回NULL。
[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. PSLIST_ENTRY WINAPI InterlockedPopEntrySList(  
  2.   __inout  PSLIST_HEADER ListHead  
  3. );  
QueryDepthSList返回元素的数量
[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. USHORT WINAPI QueryDepthSList(  
  2.   __in  PSLIST_HEADER ListHead  
  3. );  

微软的MSDN上有个例子,我复制了下来,链接:http://msdn.microsoft.com/en-us/library/windows/desktop/ms686962。代码如下。

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #include <windows.h>  
  2. #include <malloc.h>  
  3. #include <stdio.h>  
  4.   
  5. // Structure to be used for a list item; the first member is the   
  6. // SLIST_ENTRY structure, and additional members are used for data.  
  7. // Here, the data is simply a signature for testing purposes.   
  8.   
  9.   
  10. typedef struct _PROGRAM_ITEM {  
  11.     SLIST_ENTRY ItemEntry;  
  12.     ULONG Signature;   
  13. } PROGRAM_ITEM, *PPROGRAM_ITEM;  
  14.   
  15. int main( )  
  16. {  
  17.     ULONG Count;  
  18.     PSLIST_ENTRY pFirstEntry, pListEntry;  
  19.     PSLIST_HEADER pListHead;  
  20.     PPROGRAM_ITEM pProgramItem;  
  21.   
  22.     // Initialize the list header to a MEMORY_ALLOCATION_ALIGNMENT boundary.  
  23.     pListHead = (PSLIST_HEADER)_aligned_malloc(sizeof(SLIST_HEADER),  
  24.        MEMORY_ALLOCATION_ALIGNMENT);  
  25.     if( NULL == pListHead )  
  26.     {  
  27.         printf("Memory allocation failed.\n");  
  28.         return -1;  
  29.     }  
  30.     InitializeSListHead(pListHead);  
  31.   
  32.     // Insert 10 items into the list.  
  33.     for( Count = 1; Count <= 10; Count += 1 )  
  34.     {  
  35.         pProgramItem = (PPROGRAM_ITEM)_aligned_malloc(sizeof(PROGRAM_ITEM),  
  36.             MEMORY_ALLOCATION_ALIGNMENT);  
  37.         if( NULL == pProgramItem )  
  38.         {  
  39.             printf("Memory allocation failed.\n");  
  40.             return -1;  
  41.         }  
  42.         pProgramItem->Signature = Count;  
  43.         pFirstEntry = InterlockedPushEntrySList(pListHead,   
  44.                        &(pProgramItem->ItemEntry));   
  45.     }  
  46.   
  47.     // Remove 10 items from the list and display the signature.  
  48.     for( Count = 10; Count >= 1; Count -= 1 )  
  49.     {  
  50.         pListEntry = InterlockedPopEntrySList(pListHead);  
  51.   
  52.         if( NULL == pListEntry )  
  53.         {  
  54.             printf("List is empty.\n");  
  55.             return -1;  
  56.         }  
  57.     
  58.         pProgramItem = (PPROGRAM_ITEM)pListEntry;  
  59.         printf("Signature is %d\n", pProgramItem->Signature);  
  60.   
  61.     // This example assumes that the SLIST_ENTRY structure is the   
  62.     // first member of the structure. If your structure does not   
  63.     // follow this convention, you must compute the starting address   
  64.     // of the structure before calling the free function.  
  65.   
  66.         _aligned_free(pListEntry);  
  67.     }  
  68.   
  69.     // Flush the list and verify that the items are gone.  
  70.     pListEntry = InterlockedFlushSList(pListHead);  
  71.     pFirstEntry = InterlockedPopEntrySList(pListHead);  
  72.     if (pFirstEntry != NULL)  
  73.     {  
  74.         printf("Error: List is not empty.\n");  
  75.         return -1;  
  76.     }  
  77.   
  78.     _aligned_free(pListHead);  
  79.   
  80.     return 1;  
  81. }  

这里略微解释下吧!

微软自己定义的那个结构体PROGRAM_ITEM的第一项是SLIST_ENTRY类型的变量。

往InterlockedPushEntrySList和InterlockedPopEntrySList传递时传递的是自定义结构体的第一项。

结构体的地址和它的第一项的地址是同一个。

0 0
原创粉丝点击