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

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

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

InitializeSListHead,创建一个空栈

  1. void WINAPI InitializeSListHead(
  2. __inout PSLIST_HEADER ListHead//SLIST_HEADER类型的链头,供系统使用。
  3. );

InterlockedFlushSList,清空栈(感觉这个返回值没什么用的样子,难道可以先全部得到,然后根据链表中元素数量再一个一个地用?求解释。)

  1. PSLIST_ENTRY WINAPI InterlockedFlushSList(
  2. __inout PSLIST_HEADER ListHead//创建空栈时用的那个链头
  3. );

InterlockedPushEntrySList,在头添加(区别于从尾部添加),返回值为之前的第一项,如果之前为空链,则返回NULL。

  1. PSLIST_ENTRY WINAPI InterlockedPushEntrySList(
  2. __inout PSLIST_HEADER ListHead,//创建空栈时用的那个链头
  3. __inout PSLIST_ENTRY ListEntry//插入项
  4. );

InterlockedPopEntrySList,在头取出(区别于从尾部取出),返回值就是取的那个项的指针,如果之前为空链,则返回NULL。

  1. PSLIST_ENTRY WINAPI InterlockedPopEntrySList(
  2. __inout PSLIST_HEADER ListHead
  3. );

QueryDepthSList,返回元素的数量。

  1. USHORT WINAPI QueryDepthSList(
  2. __in PSLIST_HEADER ListHead
  3. );

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

  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. typedef struct _PROGRAM_ITEM {
  10. SLIST_ENTRY ItemEntry;
  11. ULONG Signature;
  12. } PROGRAM_ITEM, *PPROGRAM_ITEM;
  13.  
  14. int main( )
  15. {
  16. ULONG Count;
  17. PSLIST_ENTRY pFirstEntry, pListEntry;
  18. PSLIST_HEADER pListHead;
  19. PPROGRAM_ITEM pProgramItem;
  20.  
  21. // Initialize the list header to a MEMORY_ALLOCATION_ALIGNMENT boundary.
  22. pListHead = (PSLIST_HEADER)_aligned_malloc(sizeof(SLIST_HEADER),
  23. MEMORY_ALLOCATION_ALIGNMENT);
  24. if( NULL == pListHead )
  25. {
  26. printf("Memory allocation failed.\n");
  27. return -1;
  28. }
  29. InitializeSListHead(pListHead);
  30.  
  31. // Insert 10 items into the list.
  32. for( Count = 1; Count <= 10; Count += 1 )
  33. {
  34. pProgramItem = (PPROGRAM_ITEM)_aligned_malloc(sizeof(PROGRAM_ITEM),
  35. MEMORY_ALLOCATION_ALIGNMENT);
  36. if( NULL == pProgramItem )
  37. {
  38. printf("Memory allocation failed.\n");
  39. return -1;
  40. }
  41. pProgramItem->Signature = Count;
  42. pFirstEntry = InterlockedPushEntrySList(pListHead,
  43. &(pProgramItem->ItemEntry));
  44. }
  45.  
  46. // Remove 10 items from the list and display the signature.
  47. for( Count = 10; Count >= 1; Count -= 1 )
  48. {
  49. pListEntry = InterlockedPopEntrySList(pListHead);
  50.  
  51. if( NULL == pListEntry )
  52. {
  53. printf("List is empty.\n");
  54. return -1;
  55. }
  56.  
  57. pProgramItem = (PPROGRAM_ITEM)pListEntry;
  58. printf("Signature is %d\n", pProgramItem->Signature);
  59.  
  60. // This example assumes that the SLIST_ENTRY structure is the
  61. // first member of the structure. If your structure does not
  62. // follow this convention, you must compute the starting address
  63. // of the structure before calling the free function.
  64.  
  65. _aligned_free(pListEntry);
  66. }
  67.  
  68. // Flush the list and verify that the items are gone.
  69. pListEntry = InterlockedFlushSList(pListHead);
  70. pFirstEntry = InterlockedPopEntrySList(pListHead);
  71. if (pFirstEntry != NULL)
  72. {
  73. printf("Error: List is not empty.\n");
  74. return -1;
  75. }
  76.  
  77. _aligned_free(pListHead);
  78.  
  79. return 1;
  80. }

这里略微解释下吧!

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

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

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

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

读书笔记——Windows核心编程(8)Interlocked单向链式栈的更多相关文章

  1. 读书笔记——Windows核心编程(8)Interlocked系列函数

    先让我们来复习下小学知识 A+B=C//式中A为被加数,B为加数. A-B=C//式中A为被减数,B为减数. 再让我们来明确一个知识点:返回值为void的Windows函数意味着一定会执行成功. -- ...

  2. 读书笔记——Windows核心编程(2)比较字符串

    1. CompareString 以符合用户语言习惯的方式,EX版本使用UNICODE int CompareString( __in LCID Locale, __in DWORD dwCmpFla ...

  3. 读书笔记——Windows核心编程(15)在应用程序中使用虚拟内存

    微软的Windows提供了三种机制对内存进行操控 1 虚拟内存(最适合管理大型对象数组或大型结构数组) 2 内存映射文件(大型数据流/文件,共享数据) 3  堆(大量的小型对象) 预订地址空间区域Vi ...

  4. 读书笔记——Windows核心编程(13)Windows内存体系结构

    对于32位进程(0x0000 0000~0xFFFF FFFF),有4GB的地址空间. 每个进程都有自己专有的地址空间,当进程的各个线程运行时,它们只能访问属于该进程的内存. 这4GB其实是虚拟地址空 ...

  5. 读书笔记——Windows核心编程(2)禁止C运行时触发的所有Debug Assertion Failed对话框

    1 定义一个函数 void _invalid_parameter( const wchar_t * expression, const wchar_t * function, const wchar_ ...

  6. 《Windows核心编程》读书笔记 上

    [C++]<Windows核心编程>读书笔记 这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对 ...

  7. C++Windows核心编程读书笔记

    转自:http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E6%96%87/71405.shtml "C++Windows核心编程读书笔 ...

  8. 【转】《windows核心编程》读书笔记

    这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对实现的推断,因此不少条款和Windows实际机制可能有出入 ...

  9. windows核心编程 - 线程同步机制

    线程同步机制 常用的线程同步机制有很多种,主要分为用户模式和内核对象两类:其中 用户模式包括:原子操作.关键代码段 内核对象包括:时间内核对象(Event).等待定时器内核对象(WaitableTim ...

随机推荐

  1. CentOS6.5菜鸟之旅:识别NTFS分区

    一.前言 CentOS默认时不能识别NTFS分区的,需要那么需要安装fuse-ntfs-3g来处理了. 二.安装fuse-ntfs-3g     yum install fuse-ntfs-3g

  2. javaScript一些函数--Math()

    1.不能显式地创建一个Math对象,直接使用它就可以了: 2.Math对象不能存储数据,和String,Date对象不同: 3.前面知道了parseInt()函数会通过消去小数点后面的一切,来使一个小 ...

  3. 在C#后端处理一些结果然传给前端Javascript或是jQuery

    在C#后端处理一些结果然传给前端Javascript或是jQuery,以前Insus.NET有做过一个例子<把CS值传给JS使用 >http://www.cnblogs.com/insus ...

  4. XMLHelper.cs

    http://yunpan.cn/Q7czcYTwE8qkc  提取码 545c using System; using System.Linq; using System.Xml.Linq; usi ...

  5. OAuth2.0 基础概述

    web:http://oauth.net/2/ rfc:http://tools.ietf.org/html/rfc6749 doc:http://oauth.net/documentation/ c ...

  6. 内核移植和文件系统制作(2):linux内核最小系统和initramfs文件系统

    linux内核最小系统,使用内核版本:https://www.kernel.org/pub/linux/kernel/v3.0/linux-3.8.1.tar.bz2 1,FL2440板子的基本硬件: ...

  7. u-boot移植总结(一)start.S分析

    本次移植u-boot-2010.09是基于S3C2440的FL440板子,板子自带NANDFLASH而没有NORFLASH,所以在U-BOOT启动的过程中必须实现从NANDFLASH到SDRAM的重定 ...

  8. [moka同学笔记]Yii2.0 dropDownList的使用(二)

    方法一: <?php $psObjs = Poststatus::find()->all(); $allStatus = ArrayHelper::map($psObjs,'id','na ...

  9. 2016 一中培训 day 5 ksum

    又是一天的爆零!!!!! 原本第一题 很容易做 竟然优化过度 丢了答案 1693: ksum Time Limit 1000 ms Memory Limit 524288 KBytes Judge S ...

  10. HttpClient总结一之基本使用

    最近工作中是做了一个handoop的hdfs系统的文件浏览器的功能,是利用webhdfs提供的rest api来访问hdfs来与hdfs进行交互的,其中大量使用HttpClient,之前一直很忙,没什 ...