zoukankan      html  css  js  c++  java
  • 读书笔记——Windows核心编程(8)Interlocked单向链式栈

    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传递时传递的是自定义结构体的第一项。

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

    转载请注明出处http://blog.csdn.net/wlsgzl/article/details/17021551

  • 相关阅读:
    【java】对象赋值给另一个对象
    spring boot系列(五)spring boot 配置spring data jpa (查询方法)
    Spring Data JPA 查询
    Spring Data JPA 介绍
    OpenID简介
    OAUTH协议介绍
    URL encoding(URL编码)
    RESTful 介绍
    spring boot系列(四)spring boot 配置spring data jpa (保存修改删除方法)
    spring boot 启动报 java.lang.NoClassDefFoundError: ch/qos/logback/core/spi/LifeCycle 错误
  • 原文地址:https://www.cnblogs.com/wlsandwho/p/4202162.html
Copyright © 2011-2022 走看看