SLists使用了无锁算法来保证原子同步,以提升系统性能,避免了诸如优先级挂和互锁的问题。
注意:所有的链表项必须对齐到MEMORY_ALLOCATION_ALIGNMENT。否则会出现奇葩的错误。
(PS:看英文MSDN的API解释,我感觉这是从前插又从前取,是个栈的样子。)
InitializeSListHead,创建一个空栈
void WINAPI InitializeSListHead( __inout PSLIST_HEADER ListHead//SLIST_HEADER类型的链头,供系统使用。 );
InterlockedFlushSList,清空栈(感觉这个返回值没什么用的样子,难道可以先全部得到,然后根据链表中元素数量再一个一个地用?求解释。)
PSLIST_ENTRY WINAPI InterlockedFlushSList( __inout PSLIST_HEADER ListHead//创建空栈时用的那个链头 );
InterlockedPushEntrySList,在头添加(区别于从尾部添加),返回值为之前的第一项,如果之前为空链,则返回NULL。
PSLIST_ENTRY WINAPI InterlockedPushEntrySList( __inout PSLIST_HEADER ListHead,//创建空栈时用的那个链头 __inout PSLIST_ENTRY ListEntry//插入项 );
InterlockedPopEntrySList,在头取出(区别于从尾部取出),返回值就是取的那个项的指针,如果之前为空链,则返回NULL。
PSLIST_ENTRY WINAPI InterlockedPopEntrySList( __inout PSLIST_HEADER ListHead );
QueryDepthSList,返回元素的数量。
USHORT WINAPI QueryDepthSList( __in PSLIST_HEADER ListHead );
微软的MSDN上有个例子,我复制了下来,链接:http://msdn.microsoft.com/en-us/library/windows/desktop/ms686962。代码如下。
#include <windows.h> #include <malloc.h> #include <stdio.h> // Structure to be used for a list item; the first member is the // SLIST_ENTRY structure, and additional members are used for data. // Here, the data is simply a signature for testing purposes. typedef struct _PROGRAM_ITEM { SLIST_ENTRY ItemEntry; ULONG Signature; } PROGRAM_ITEM, *PPROGRAM_ITEM; int main( ) { ULONG Count; PSLIST_ENTRY pFirstEntry, pListEntry; PSLIST_HEADER pListHead; PPROGRAM_ITEM pProgramItem; // Initialize the list header to a MEMORY_ALLOCATION_ALIGNMENT boundary. pListHead = (PSLIST_HEADER)_aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT); if( NULL == pListHead ) { printf("Memory allocation failed. "); return -1; } InitializeSListHead(pListHead); // Insert 10 items into the list. for( Count = 1; Count <= 10; Count += 1 ) { pProgramItem = (PPROGRAM_ITEM)_aligned_malloc(sizeof(PROGRAM_ITEM), MEMORY_ALLOCATION_ALIGNMENT); if( NULL == pProgramItem ) { printf("Memory allocation failed. "); return -1; } pProgramItem->Signature = Count; pFirstEntry = InterlockedPushEntrySList(pListHead, &(pProgramItem->ItemEntry)); } // Remove 10 items from the list and display the signature. for( Count = 10; Count >= 1; Count -= 1 ) { pListEntry = InterlockedPopEntrySList(pListHead); if( NULL == pListEntry ) { printf("List is empty. "); return -1; } pProgramItem = (PPROGRAM_ITEM)pListEntry; printf("Signature is %d ", pProgramItem->Signature); // This example assumes that the SLIST_ENTRY structure is the // first member of the structure. If your structure does not // follow this convention, you must compute the starting address // of the structure before calling the free function. _aligned_free(pListEntry); } // Flush the list and verify that the items are gone. pListEntry = InterlockedFlushSList(pListHead); pFirstEntry = InterlockedPopEntrySList(pListHead); if (pFirstEntry != NULL) { printf("Error: List is not empty. "); return -1; } _aligned_free(pListHead); return 1; }
这里略微解释下吧!
微软自己定义的那个结构体PROGRAM_ITEM的第一项是SLIST_ENTRY类型的变量。
往InterlockedPushEntrySList和InterlockedPopEntrySList传递时传递的是自定义结构体的第一项。
结构体的地址和它的第一项的地址是同一个。