练习一下linux中的list函数。

所有的list函数见 include/linux/list.h

自己从 include/linux/list.h 拷贝了一些函数到自己的list.c中, 然后练习了一下。

没有别的目的,就是想熟练一下。毕竟linux内核代码中试用了大量的list函数。

list的函数太方便使用了。

文件:list.c

  1 #include <stdio.h>
  2 // #include <linux/list.h>
  3
  4 struct list_head {
  5  struct list_head *next, *prev;
  6 };
  7
  8 #define LIST_HEAD_INIT(name) { &(name), &(name) }
  9
 10 static inline void INIT_LIST_HEAD(struct list_head *list)
 11 {
 12  list->next = list;
 13  list->prev = list;
 14 }
 15
 16 static inline void __list_add(struct list_head *new,
 17          struct list_head *prev,
 18          struct list_head *next) //ËüÖ»Êǽ«newÌí¼Óµ½prevºÍnextÖ®¼ä
 19 {
 20  next->prev = new;
 21  new->next = next;
 22  new->prev = prev;
 23  prev->next = new;
 24 }
 25
 26 static inline void list_add_tail(struct list_head *new, struct list_head *head)
 27 {
 28  __list_add(new, head->prev, head);
 29 }
 30
 31 static inline int list_empty(const struct list_head *head)
 32 {
 33  return head->next == head;
 34 }
 35
 36
 37 #undef offsetof
 38 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
 39
 40 /**
 41  *  * container_of - cast a member of a structure out to the containing structure
 42  *   * @ptr:        the pointer to the member.
 43  *    * @type:       the type of the container struct this is embedded in.
 44  *     * @member:     the name of the member within the struct.
 45  *      *
 46  *       */
 47 #define container_of(ptr, type, member) ({                       48         const typeof( ((type *)0)->member ) *__mptr = (ptr);     49         (type *)( (char *)__mptr - offsetof(type,member) );})
 50
 51
 52 #define list_entry(ptr, type, member)  53         container_of(ptr, type, member)
 54
 55
 56 /**
 57  *  * list_for_each_entry  -       iterate over list of given type
 58  *   * @pos:        the type * to use as a loop cursor.
 59  *    * @head:       the head for your list.
 60  *     * @member:     the name of the list_struct within the struct.
 61  *      */
 62 #define list_for_each_entry(pos, head, member)                           63         for (pos = list_entry((head)->next, typeof(*pos), member);       64              &pos->member != (head);     65              pos = list_entry(pos->member.next, typeof(*pos), member))
 66
 67 #define list_for_each(pos, head)  68         for (pos = (head)->next; pos != (head); pos = pos->next)
 69
 70
 71 struct devlist {
 72         struct list_head        list;
 73         char * name;
 74 };
 75
 76 struct devlist dev0 = {
 77         .list = LIST_HEAD_INIT(dev0.list),
 78         .name = NULL,
 79 };
 80
 81 void main(void) {
 82     struct list_head *l;
 83     struct devlist * pdev = NULL;
 84     int empty = list_empty(&dev0.list);
 85     if(empty)
 86         printf("the device list is empty!\n");
 87     struct devlist dev1;
 88     dev1.name = "device1";
 89     list_add_tail(&dev1.list, &dev0.list);
 90     struct devlist dev2 = {{}, "device2"};
 91     // dev2.name = "device2";
 92     list_add_tail(&dev2.list, &dev0.list);
 93
 94     empty = list_empty(&dev0.list);
 95     if(!empty)
 96         printf("the device list is not empty!\n");
 97
 98     list_for_each(l, &dev0.list) {
 99             pdev = list_entry(l, struct devlist, list);
100             printf("the device name is %s\n", pdev->name);
101     }
102 }

输出结果:

1 $ gcc -o list list.c
2 $ ./list
3 the device list is empty!
4 the device list is not empty!
5 the device name is device1
6 the device name is device2
时间: 2024-09-30 13:26:32

练习一下linux中的list函数。的相关文章

Linux中的fork()函数

 一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程, 也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事. 一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间.然后把原来的进程的所有值都 复制到新的新进程中,只有少数值与原来的进程的值不同.相当于克隆了一个自己. 我们来看一个例子: /* *  fork_test.c *  version 1

linux中内核延时函数

第一类延时函数原型是:(忙等) void ndelay(unsigned long nsecs); void udelay(unsigned long usecs); void mdelay(unsigned long msecs); 说明:内核函数 ndelay, udelay, 以及 mdelay 对于短延时好用, 分别延后执行指定的纳秒数, 微秒数或者毫秒数. 它们涉及到的延时常常是最多几个毫秒. 第二类延时函数原型是:(使进程进入休眠) void msleep(unsigned int

Linux中的入口函数main

main()函数,想必大家都不陌生了,从刚开始写程序的时候,大家便开始写main(),我们都知道main是程序的入口.那main作为一个函数,又是谁调用的它,它是怎么被调用的,返回给谁,返回的又是什么?这次我们来探讨一下这个问题. 1. main()函数的形式先来说说main函数的定义,较早开始写C程序的肯定都用过这样的定义void main(){},其实翻翻C/C++标准,从来没有定义过void main().在C标准中main的定义只有两种:        int main(void)   

linux中字符串转换函数 simple_strtoul

Linux内核中提供的一些字符串转换函数: lib/vsprintf.c [html] view plain copy print? 1. unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base) 2. unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base) 3. long simple_st

Linux中backtrace()系列函数的应用实例

一.引言 backtrace()系列函数可用来输出代码出错时的函数调用关系. A backtrace is the series of currently active function calls for the program. #include <execinfo.h> int backtrace(void **buffer, int size); char **backtrace_symbols(void *const *buffer, int size); void backtrac

Linux中快速找到函数原型的方法

在Linux的控制台,输入man命令,即可查看对应函数原型,用法,及所需要的头文件啦 eg: man stat 但是你会发现这个stat是一个Linux 命令,不是我们想查找的函数.那是因为我们找错了章节.stat函数的用法应该在第二章节,即man 2 stat;

linux中的__builtin_except()函数

在看代码的时候看到两个宏函数:likely()   unlikely() #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) __builtin_expect()大致作用是处理分支预测,让编译器编译的时候可以做一些优化,优化可能性大的分支程序 if( likely(x) ) --->表示if内为真的可能性很大 if(unlikely(x) ) -->表示if内为假

Linux中的动态函数库和静态函数库的比较

库函数既提高了代码的利用率,又屏蔽了函数内部实现的细节,给不同开发者提供了统一的接口.从实现来看,库函数可以分为动态函数库和静态函数库.同一组函数,可以根据需要封装成静态库和动态库.那么生成静态库和动态库有什么区别?静态库和动态库对函数的实现上各有些什么要求?两者对内存各有什么影响呢?下面就带着这些问题一起开探讨. 静态库和动态库生成方式的区别为了简化,下面以一个只有一个函数的库的实现来说明.库函数的代码demo.c如下:/************************************

linux中的fork函数的基本用法

代码: 1 #include <iostream> 2 #include <string> 3 #include <cstdio> 4 #include <unistd.h> 5 #include <sys/wait.h> 6 7 using namespace std; 8 9 int main(int argc,char* argv[]){ 10 11 pid_t pid; 12 for(int i = 0; i < 1; i++){