易截截图软件、单文件、免安装、纯绿色、仅160KB

深入理解Linux内核中的链表

  最近,开始研读一下Linux的内核代码,刚一开始,就有令人惊叹的发现,不得不感叹内核代码设计得之美!单是最常用的链表也设计得不得不令人佩服!
1.1.链表list_head
    include/linux/list.h
    很经典,链表在内核中很常用,例如管理进程,进程的各个状态队列都是使用这个双向链表实现的。内核中的链表定义成和数据无关的形式,而不是通常我们使用的链表格式,例如
typedef struct _list{
    Elemtype elem;
    struct _list *next;
}list;
内核中的链表定义为
struct list_head{
    struct list_head *next, *prev;
};
可见,这个链表节点中不包含任何数据,只有两个指针。当需要使用链表来组织数据结构时,这个结构中就包含一个list_head成员,例如
struct _list_struct{
    Elemtype elem;
    struct list_head list;
    ...
};
显而易见,链表实现成和数据分离的好处是,不用为每种数据都定义链表操作,可以使用统一的链表操作即可。但是问题是:只知道数据成员list的地址,怎样去访问自身以及其他成员呢?
#define list_entry(ptr,type,member)    \
    container_of(ptr,type,member)
而container_of(ptr,type,member)宏定义在include/list/kernel.h中
#define container_of(ptr,type,member)    ({
    const typeof( ((type *)0)->member) *__ptr=ptr;
    (type *)( (char *)__ptr - offsetof(type,member));})
    上面的宏有几点需要解释:
1)typeof(type) 宏
    typeof(type) 宏返回变量type的类型,例如:int a; typeof(a) b;等价于int b;
2)offsetof(type,member)宏
    它定义在include/linx/stddef.h中,如下:
#define offsetof(TYPE, MEMBER)  ((size_t) &((TYPE *)0)->MEMBER)
这个宏返回member在type类型中的偏移量,type是一个结构,例如:
typeof(list_head,next);返回0,也就是返回相对于结构起始地址的偏移量。
3)为什么要使用typeof(((type *)0)->member)来定义指针 __ptr,而不是这样:
const typeof(member) *__ptr=ptr;?
    其实,这个很简单,因为member是结构的成


相关文档:

介绍一种多LINUX系统的实现方法

   介绍一种多LINUX系统的实现方法
            
 
目前,LINUX版本众多,桌面环境包括Gnome,KDE等,在一台电脑上安装Windows系统和多LINUX系统很有必要.这里介绍一种方法,多个LINUX系统之间各自独立,互不访问,各自都能访问Windows资源. ......

linux下安装jdk及配置环境变量

apache-tomact的安装
一.JDK的安装 
1. 先从网上下载jdk(jdk-1_5_0-linux-i586.rpm) ,推荐SUN的官方网站http://www.sun.com/,下载后放在/home目录中(可以使用winscp软件施行上传),当然其它地方也行。
进入安装目录
#cd /home
#cp jdk-1_5_0_-linux-i586.rpm.bin  /usr/local (拷贝命令)
#cd /usr/lo ......

Linux 安装FFmpeg

在Redhat 9.0成功安装了ffmpeg,现记录如下。
  1、下载ffmpeg。
  http://download.chinaunix.net/do ... 532&ResourceID=2990
  我是在这个网址上下载ffmpeg-0.4.9-p20051120.tar.bz2,看网上有人用的是svn下载,但是我的机子中没有svn客户端,然后就在网上搜索,下载了这个版本。如果利用svn可以下载ffmpeg� ......

Linux内核访问外设I/O资源的方式

我们知道默认外设I/O资源是不在Linux内核空间中的(如sram或硬件接口寄存器等),若需要访问该外设I/O资源,必须先将其地址映射到内核空间中来,然后才能在内核空间中访问它。
 
Linux内核访问外设I/O内存资源的方式有两种:动态映射(ioremap)和静态映射(map_desc)。
 
一、动态映射(ioremap)方式
 
� ......

linux gcc 的编译过程 详解

gcc的编译过程分为四步,分别为:
(1)预编译 (Pre-Processing)
(2)编译 (Compiling)
(3)汇编 (Assembling)
(4)链接 (Linking)
以hello.c为例说明:
#include<stdio.h>
int main(void)
{
 printf("Hello World!");
 return 0;
}
(1)预编译阶段 (Pre-Processing)
&nbs ......
© 2009 ej38.com All Rights Reserved. 关于E健网联系我们 | 站点地图 | 赣ICP备09004571号