练习一下linux中的list函数。
所有的list函数见 include/linux/list.h
自己从 include/linux/list.h 拷贝了一些函数到自己的list.c中, 然后练习了一下。
没有别的目的,就是想熟练一下。毕竟linux内核代码中试用了大量的list函数。
list的函数太方便使用了。
文件:list.c
#include <stdio.h>
// #include <linux/list.h> struct list_head {
struct list_head *next, *prev;
}; #define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name) static inline void INIT_LIST_HEAD(struct list_head *list)
{
list->next = list;
list->prev = list;
} static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next) //ËüÖ»Êǽ«newÌí¼Óµ½prevºÍnextÖ®¼ä
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
} static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
} static inline int list_empty(const struct list_head *head)
{
return head->next == head;
} #undef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) /**
* * container_of - cast a member of a structure out to the containing structure
* * @ptr: the pointer to the member.
* * @type: the type of the container struct this is embedded in.
* * @member: the name of the member within the struct.
* *
* */
#define container_of(ptr, type, member) ({ \
const typeof( ((type *))->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );}) #define list_entry(ptr, type, member) \
container_of(ptr, type, member) /**
* * list_for_each_entry - iterate over list of given type
* * @pos: the type * to use as a loop cursor.
* * @head: the head for your list.
* * @member: the name of the list_struct within the struct.
* */
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member)) #define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next) struct devlist {
struct list_head list;
char * name;
}; struct devlist dev0 = {
.list = LIST_HEAD_INIT(dev0.list),
.name = NULL,
}; /* static initiate head list*/
// LIST_HEAD(hl);
struct list_head hl = LIST_HEAD_INIT(hl); void main(void) {
/* dynamic initiate head list. */
INIT_LIST_HEAD(&hl);
struct list_head *l;
struct devlist * pdev = NULL;
int empty = list_empty(&hl);
if(empty)
printf("the device list is empty!\n");
struct devlist dev1;
dev1.name = "device1";
list_add_tail(&dev1.list, &hl);
struct devlist edev1 = {{}, "entry device1"};
list_add_tail(&edev1.list, &dev0.list);
struct devlist dev2 = {{}, "device2"};
list_add_tail(&dev2.list, &hl);
struct devlist edev2 = {{}, "entry device2"};
list_add_tail(&edev2.list, &dev0.list); empty = list_empty(&hl);
if(!empty)
printf("the device list is not empty!\n"); list_for_each_entry(pdev, &dev0.list, list){
printf("the device name is %s\n", pdev->name);
} list_for_each(l, &hl) {
// for (l = (&hl)->next; l != (&hl); l = l->next){
// printf("l is: %p, head is: %p \n", l, &hl);
pdev = list_entry(l, typeof(dev0), list);
printf("the device name is %s\n", pdev->name);
}
}
输出结果:
$ ./list
the device list is empty!
the device list is not empty!
the device name is entry device1
the device name is entry device2
the device name is device1
the device name is device2
练习一下linux中的list函数。的更多相关文章
- 深入解析Linux中的fork函数
1.定义 #include <unistd.h> #include<sys/types.h> pid_t fork( void ); pid_t 是一个宏定义,其实质是int, ...
- 如何测试Linux 中的wait函数能不能等待子进程的子进程?
#include <stdio.h> #include <stdlib.h> int main() { pid_t pid = fork(); switch(pid) { : ...
- [fork]Linux中的fork函数详解
---------------------------------------------------------------------------------------------------- ...
- 关于linux中的system函数
Linux下使用system()函数一定要谨慎 https://blog.csdn.net/senen_wakk/article/details/51496322 system()正确应用 https ...
- Linux中的入口函数main
main()函数,想必大家都不陌生了,从刚开始写程序的时候,大家便开始写main(),我们都知道main是程序的入口.那main作为一个函数,又是谁调用的它,它是怎么被调用的,返回给谁,返回的又是什么 ...
- Linux中的读函数与块高速缓存
为了提高Linux块设备读写的效率,Unix会在内存中建立块高速缓存,块高速缓存存储了系统最近读的数据块和刚刚写入的数据块,也就是说IO访问其实是和块高速缓存打交道的(直接IO除外),块高速缓存会适时 ...
- Unix/Linux中的fork函数
fork函数介绍 一个现有进程可以调用fork函数创建一个新进程.该函数定义如下: #include <unistd.h> pid_t fork(void); // 返回:若成功则在子进程 ...
- linux中内核延时函数 (转)
第一类延时函数原型是:(忙等) void ndelay(unsigned long nsecs); void udelay(unsigned long usecs); void mdelay(unsi ...
- linux中字符串转换函数 simple_strtoul【转】
转自:http://blog.csdn.net/tommy_wxie/article/details/7480087 Linux内核中提供的一些字符串转换函数: lib/vsprintf.c [htm ...
随机推荐
- shell基础——变量定义
快速参考: 变量定义格式: 变量名=值 str1="hello world" # define a string var str2=hello # define a string ...
- CreateFile函数详解(确实很详细)
CreateFile The CreateFile function creates or opens the following objects and returns a handle that ...
- 2014第13周四Webservice概念问题记
晚上回来看网页学习了这两天一直疑惑的两个问题: 1.REST和SOAP架构下的Webservice的区别? 2.axis2和CXF的区别. 大部分是理论,暂时摘录一下,以后有更多实践后再回顾. 一.R ...
- vs2008 + OpenCV-2.1.0-win32-vs2008安装
vs2008 + OpenCV-2.1.0-win32-vs2008安装 1. 安装vs2008+sp12. 安装opencv-2.1.0-win32-vs2008,假设安装目录为c:/opencv2 ...
- AndroidUI 布局动画-点九PNG技术
下面是正常情况与使用点9切图以后的效果对比: <Button android:id="@+id/button1" android:layout_width="fil ...
- Struts2 四、Struts2 处理流程
1. 一个请求在Struts2框架中的处理步骤: a) 客户端初始化一个指向Servlet容器的请求: b) 根据Web.xml配置,请求首先经过ActionContextCleanUp过滤器,其为可 ...
- 编绎报错,解决方法objc_msgSend too many arguments to function call,expected 0, have3 (转)
编绎报错,objc_msgSend too many arguments to function call,expected 0, have3 解决方法:
- spoj 8222 Substrings (后缀自动机)
spoj 8222 Substrings 题意:给一个字符串S,令F(x)表示S的所有长度为x的子串中,出现次数的最大值.求F(1)..F(Length(S)) 解题思路:我们构造S的SAM,那么对于 ...
- 《Qt编程的艺术》——8.2 显示目录层次
现在我们准备通过创建一个小程序来获得关于InterView的实践经验,使用QDirModel和拿来就用的view,来在四个不同的view中显示主目录,如图8.5所示.在代码里,除了例行公事先实例化一个 ...
- git 删除远程主分支及其它操作
1. 删除远程分支 如果不再需要某个远程分支了,比如搞定了某个特性并把它合并进了远程的 master 分支(或任何其他存放稳定代码的地方),可以用这个非常无厘头的语法来删除它:git push [远程 ...