




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、这两天想看看memcached的实现,所以先学习了libevent,使用起来还是比较简单的,其实是对select/poll/kqueue等的封装,学习libevent过程中又遇到了linux下队列的使用,简单分析如下,权当做记录: libevent中的例子中使用的是FreeBSD下的queue.h,在linux的/usr/include/sys/queue.h也有该头文件,但是是一个缩减版本,而且没有看到queue 的access method,不知道是不是跟我们的linux服务器版本有关,没办法google了一下,找到了FreeBSD 下queue.h的定义,我们看一下tail q
2、ueue的定义 C代码 1. #define TAILQ_HEAD(name, type) 2. struct name
3、 3. struct type *tqh_first; /* first element */ 4. struct type *tqh_last; /* addr of last next element */ 5.
4、 6. 7. #define TAILQ_ENTRY(type) 8. struct
5、160; 9. struct type *tqe_next; /* next element */ 10. struct type *tqe_prev;/*
6、0;addr of previous next element*/ 11.
7、60; 12. 13. #define TAILQ_INIT(head) do
8、 14. (head)->tqh_first = NULL; 15. (head)->tqh_last = &(head)->tqh_first;
9、0; 16. while (0) 17. 18. #define TAILQ_INSERT_TAIL(head, elm, field) do 19. (elm)->field.tqe_next
10、0;= NULL; 20. (elm)->field.tqe_prev = (head)->tqh_last; 21. *(head)->tqh_last = (elm);
11、160;/将elm赋给最后一个元素 22. (head)->tqh_last = &(elm)->field.tqe_next; 23. while (0) 24.
12、60; 25. #define TAILQ_INSERT_BEFORE(listelm, elm, field) do 26. (elm)->field.tqe_prev = (listelm)->field.tqe_prev; 27.
13、0;(elm)->field.tqe_next = (listelm); 28. *(listelm)->field.tqe_prev = (elm); 29.
14、60;(listelm)->field.tqe_prev = &(elm)->field.tqe_next; 30. while (0) 31. #define TAILQ_FIRST(head) (head)->tqh_first) 32. 33. #define TAILQ_NEXT(elm,
15、60;field) (elm)->field.tqe_next) 34. . 我们就先分析上面的这些定义,先看个应用的例子 C代码 1. #include <stdio.h> 2. #include <stdlib.h> 3. #include "queue.h" 4. 5. str
16、uct QUEUE_ITEM 6. int value; 7. TAILQ_ENTRY(QUEUE_ITEM) entries; 8. ; 9. TAILQ_HEAD(,QUEUE_ITEM) queue_head; 10. int main(int argc,char *argv) 11.
17、0; struct QUEUE_ITEM *item; 12. struct QUEUE_ITEM *tmp_item; 13. 14. ccc TAILQ_INIT(&queue_head); 15. int i=0; 16.
18、 for(i=5;i<10;i+=2) 17. item=malloc(sizeof(item); 18. item->value=i; 19. TAILQ_INSERT_TAIL(&queue_head
19、, item, entries); 20. 21. 22. struct QUEUE_ITEM *ins_item; 23. ins_item=malloc(sizeof(ins_item); 24. 25.
20、0; ins_item->value=100; 26. TAILQ_INSERT_BEFORE(item,ins_item,entries); 27. 28. 29. tmp_item=TAILQ_FIRST(&queue_head); 30. printf("first elemen
21、t is %dn",tmp_item->value); 31. 32. tmp_item=TAILQ_NEXT(tmp_item,entries); 33. printf("next element is %dn",tmp_item->value); 34. 35.
22、60; tmp_item=TAILQ_NEXT(tmp_item,entries); 36. printf("next element is %dn",tmp_item->value); 37. 38. tmp_item=TAILQ_NEXT(tmp_item,entries); 39. print
23、f("next element is %dn",tmp_item->value); 40. 41. 结果: Java代码 1. first element is 5 2. next element is 7 3. next element is 100 4. next ele
24、ment is 9 分析: QUEUE_ITEM 是我们定义的存放在队列里的东东,简单起见只包括一个int值 TAILQ_ENTRY(QUEUE_ITEM) entries 主要是存放下一个对象和前一个对象的指针,具体见 header 根据头文件进行宏替换后,实际我们声明的是这样的结构: C代码 1. struct QUEUE_ITEM 2. int value;
25、160; 3. struct 4. struct QUEUE_ITEM *tqe_next;
26、 5. struct QUEUE_ITEM *tqe_prev; 6. entries; 7. ; 8. TAILQ_HEAD(,QUEUE_ITEM) queue_head; 实际是 C代码 1. struct
27、0; 2. struct QUEUE_ITEM *tqh_first; 3. struct QUEUE_ITEM *tqh_last; 4. queue_he
28、ad; 接着我们定义了QUEUE_ITEM的两个指针变量item和tmp_item TAILQ_INIT(&queue_head); 相当于是 C代码 1. do 2. (&queue_head)->tqh_first = NULL;
29、;3. (&queue_head)->tqh_last = &(&queue_head)->tqh_first; 4. while (0); head的初始化如 下图1 接着我们通过循环分配了几个元素,并赋值 C代码 1. TAILQ_INSERT_TAIL(&queue_head, item,&
30、#160;entries); 相当于执行 2. do 3. (item)->entries.tqe_next = NULL; 4. (item)->entries.tqe_prev = (&queue_head)->tqh_last;
31、0; 5. *(&queue_head)->tqh_last = (item); 6. (&queue_head)->tqh_last&
32、#160;= &(item)->entries.tqe_next; 7. while (0); Int a =1;Int*pa=&a;Int b =2;Int*pb=&b;Int *p =&pa;*p=pb;也就是我们的循环执行下面代码段,结果分析见图2,3 C代码 1. for(i=5;i<10;i+=2)
33、60;2. item=malloc(sizeof(item); 3. item->value=i; 4. do 5. (item)->entries.tqe_next = NULL; 6. &
34、#160; /首次执行相当于item->entries.tqe_prev=&(&queue_head)->tqh_first 7. /以后执行相当于是(item)->entries.tqe_prev=&(前一个item)->entries.tqe_next; 8. (i
35、tem)->entries.tqe_prev = (&queue_head)->tqh_last; 9. /首次执行相当于(&queue_head)->tqh_first=item 10. /以后执行相当于是(前一个item)->entries.tqe_next=当前item 11
36、. *(&queue_head)->tqh_last = (item); /填充内容12. (&queue_head)->tqh_last = &(item)->entries.tqe_next; /占位置,占个地13.
37、while (0); 14. C代码 1. 最终建立的链表结构如图,下面看一下insert操作,经过宏替换后代码如下 2. 3. struct QUEUE_ITEM *ins_item; 4. ins_item=malloc(sizeof(ins_item); 5. ins_item->value=100; 6. 7. do
38、;8. (ins_item)->entries.tqe_prev = (item)->entries.tqe_prev; 9. (ins_item)->entries.tqe_next = (item); 10. /这句话体现了TAILQ的特色,tqe_prev是前一个元素的下个元素地址, 11.
39、0; /所以正好应该是当前插入item的地址 12. *(item)->entries.tqe_prev = (ins_item); 13. (item)->entries.tqe_prev = &(ins_item)->entries.tqe_next; 14. while (0); 总结:TAILQ的
40、最大特点就是每个entry的二级指针tqe_prev其存放的是前一个元素的下个元素地址,呵呵,听起来都很拗口 现在就是不知道为什么linux的queue.h只有建立tailq的宏定义而缺少所有的access method,初涉linux c编程,请大家指教 附经过宏替换后的所有代码 C代码 1. #include "stdio.h" 2. #include "stdlib.h" 3. struct QUEUE_ITEM
41、 4. int value; 5. struct 6. struct QUEUE_ITEM *tqe_next; 7. struct QUEUE_ITEM *tqe_prev
42、; 8. entries; 9. ; 10. struct 11. struct QUEUE_ITEM *tqh_first; 12. struct QUEUE_ITEM *tqh_last; 13. queue_head; 14.
43、160;15. int main(int argc,char *argv) 16. struct QUEUE_ITEM *item; 17. struct QUEUE_ITEM *tmp_item; 18. 19. do 20.
44、0; (&queue_head)->tqh_first = NULL; 21. (&queue_head)->tqh_last = &(&queue_head)->tqh_first; 22. while (0); 23
45、. 24. int i=0; 25. for(i=5;i<10;i+=2) 26. item=malloc(sizeof(item); 27. item->value=i; 28
46、. do 29. (item)->entries.tqe_next = NULL; 30. /首次执行相当于item->entr
47、ies.tqe_prev=&(&queue_head)->tqh_first 31. /以后执行相当于是(item)->entries.tqe_prev=&(前一个item)->entries.tqe_next; 32. (i
48、tem)->entries.tqe_prev = (&queue_head)->tqh_last; 33. /首次执行相当于(&queue_head)->tqh_first=item 34. /以后执行相当于是(前
49、一个item)->entries.tqe_next=当前item 35. *(&queue_head)->tqh_last = (item); 36. (&queue_head)->tqh_last =&
50、#160;&(item)->entries.tqe_next; 37. while (0); 38. 39. 40. struct QUEUE_ITEM *ins_item; 41. ins
51、_item=malloc(sizeof(ins_item); 42. 43. ins_item->value=100; 44. do 45. (ins_item)->entries.tqe_prev = (item)->entries.tqe_prev; 46. (ins_item)->entries.tqe_next = (item);
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 难点解析人教版八年级物理上册第4章光现象-光的色散综合测评试卷(含答案详解版)
- 2025年电影数字化游戏联动岗位晋升考核试卷
- 达标测试人教版八年级物理上册第6章质量与密度-质量必考点解析试题(详解)
- 难点解析人教版八年级物理上册第5章透镜及其应用专项测试试卷(详解版)
- 基于思维导图提升学生数学核心素养的实践研究
- 综合解析苏科版八年级物理上册《物态变化》定向练习试题(解析卷)
- 考点解析人教版八年级上册物理光现象《光的直线传播》同步测评试卷(解析版)
- 校长在秋冬季校园安全工作专题会议上的讲话:以“时时放心不下”之责护秋冬校园平安
- 2024年集中式饮用水水源地监测考核试卷
- 和君咨询合同(标准版)
- 《接触网的维修管理》课件
- 高中学校三年发展规划
- 云南省2024-2025学年高二上学期11月期中考试数学试题含答案
- 前列腺癌内分泌治疗
- 历史常识单选题100道及答案解析
- 《中医基础理论》课程教案
- 风电场道路及风机基础工程冬季施工方案
- DL∕T 1860-2018 自动电压控制试验技术导则
- 国家各年级学生体质健康测试项目及评分标准
- QCT1196-2023车载冰箱要求
- 钢结构高强度环槽铆钉连接技术规程
评论
0/150
提交评论