当前位置: 首页 > news >正文

html5能单独做网站吗网络优化工程师前景

html5能单独做网站吗,网络优化工程师前景,沈阳做企业网站的,字画价格网站建设方案理解Linux内核中的container_of宏 文章目录 理解Linux内核中的container_of宏1、了解C语言中的struct内存表示2、Linux内核的container_of宏实现理解3、Linux内核的container_of使用 Linux 内核包含一个名为 container_of 的非常有用的宏。本文介绍了解 Linux 内核中的 contain…

理解Linux内核中的container_of宏

文章目录

  • 理解Linux内核中的container_of宏
    • 1、了解C语言中的struct内存表示
    • 2、Linux内核的container_of宏实现理解
    • 3、Linux内核的container_of使用

Linux 内核包含一个名为 container_of 的非常有用的宏。本文介绍了解 Linux 内核中的 container_of 宏。本文包括一个简单的程序,该程序说明了如何使用此宏,并解释了为什么它如此有用。

1、了解C语言中的struct内存表示

C 中的结构是 C 编程语言的一个强大功能。它们允许您通过将不同的变量分组到一个名称下来创建复杂的数据类型。那么,struct在内存中是如何表示的呢?例如,我们创建一个struct,并访问它的成员地址。

struct Student {int age;float grade;char name[50];int weight;
}__attribute__((packed));

请注意,为了方便演示这里使用了结构成员对齐。关于C语言的结构成员对齐,请参考:C语言结构成员对齐、填充和数据打包

那么,结构体Student在内存中的表示如下:

在这里插入图片描述

结构体的成员地址访问如下:

#include <stdlib.h>
#include <string.h>struct Student {int age;float grade;char name[50];int weight;
}__attribute__((packed));int main(int argc, char* argv[]) {struct Student st1;st1.age = 17;st1.grade = 7;st1.weight = 120;memset(st1.name, 0, sizeof(st1.name));memcpy(st1.name, "Jenson", 6);printf("sizeof struct = %d\n", sizeof(struct Student));printf("st1's address = %p\n", &st1);printf("st1.age = %p\n", &st1.age);printf("st1.grade = %p\n", &st1.grade);printf("st1.name = %p\n", &st1.name[0]);printf("st1.weight = %p\n", &st1.weight);printf("-------------------\n");printf("age'addr = %#lx\n", ((unsigned long)&st1));printf("grade'addr = %#lx\n", ((unsigned long)&st1 + sizeof(st1.age)));printf("name'addr = %#lx\n", ((unsigned long)&st1 + sizeof(st1.age) + sizeof(st1.grade)));printf("weight's addr = %#lx\n", ((unsigned long)&st1 + sizeof(st1.age) + sizeof(st1.grade) + sizeof(st1.name)));return 0;
}

我们将得到如下结果:

sizeof struct = 62
st1's address = 0x7fe806bb28
st1.age = 0x7fe806bb28
st1.grade = 0x7fe806bb2c
st1.name = 0x7fe806bb30
st1.weight = 0x7fe806bb62
-------------------
age'addr = 0x7fe806bb28
grade'addr = 0x7fe806bb2c
name'addr = 0x7fe806bb30
weight's addr = 0x7fe806bb62

如果结构体没有使用__attribute__((packed)),则name成员与weight成员将有两个字节的差异,因为编译器对结构体填充了两个字节,从而达到内存对齐的目的。

2、Linux内核的container_of宏实现理解

在Linux内核中,container_of宏的使用非常普遍,其实现如下:

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE*)0)->MEMBER) 
#define container_of(ptr, type, member) ({           const typeof(((type *)0)->member)*__mptr = (ptr);     (type *)((char *)__mptr - offsetof(type, member)); }) 

container_of宏接受3个参数:

  • ptr – 指向成员的指针。
  • type – 嵌入其中的容器结构的类型。
  • member – 结构中成员的名称。
  • 它返回成员的容器结构的地址。

为了方便理解,我们将Linux内核的container_of宏应用到用户空间程序中,示例代码如下:

#include  <stdio.h>#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)#define container_of(ptr, type, member) ({         \const typeof( ((type *)0)->member ) *__mptr = (ptr); \(type *)( (char *)__mptr - offsetof(type,member) );})int main(void)
{struct sample {int mem1;char mem2;};struct sample sample1;printf("Address of Structure sample1 (Normal Method) = %p\n", &sample1);printf("Address of Structure sample1 (container_of Method) = %p\n", container_of(&sample1.mem2, struct sample, mem2));return 0;
}

因为我们已经知道结构sample1 的地址,那么,程序输出的地址应该相同还是不同? 让我们看看输出。

Address of Structure sample1 (Normal Method) = 0x7feeaf2598
Address of Structure sample1 (container_of Method) = 0x7feeaf2598

可以知道,示例程序输出的结果是相同的,那么,container_of宏是如何工作的呢?让我们看看内核中的代码:

/*** 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 *)0)->member ) *__mptr = (ptr); \(type *)( (char *)__mptr - offsetof(type,member) );})

下面,我们将一步一步来解释这个宏是如何工作的?首先,让我们看第一行代码:

 const typeof( ((type *)0)->member ) *__mptr = (ptr);

对于const关键字在这里就不做解释了。在这行代码中,我们对typeof感兴趣。

typeof()

typeof是非标准 GCC 扩展。GCC 扩展的类型,允许我们引用表达式的类型,并可用于声明变量。例如:

int x = 5;
typeof(x) y = 6;
printf("%d %d\n", x, y);

零指针引用

但是零指针取消引用呢?获取成员的类型是一个小小的指针魔术。它不会崩溃,因为表达式本身永远不会被计算。编译器关心的只是它的类型。如果我们要求回问地址,也会发生同样的情况。编译器同样不关心值,它只是将成员的偏移量添加到结构的地址中,在本例中为 0,并返回新地址。如下面代码所示:

struct s {char m1;char m2;
};/* This will print 1 */
printf("%d\n", &((struct s*)0)->m2);
#include  <stdio.h>
int main(void)
{struct sample {int mem1;char mem2;};printf("Offset of the member = %d\n", &((struct s*)0)->mem2);return 0;
}

因此,我们从:

const typeof( ((type *)0)->member ) *__mptr = (ptr)

这行代码可以知道,它创建了局部常量指针变量。正如示例代码所实现的那样:

const typeof( ((type *)0)->member ) *__mptr = (ptr)—–> const char * __mptr = &sample1.mem2

接下来,让我们分析container_of宏的第二行代码:

 (type *)( (char *)__mptr - offsetof(type,member) )

offsetof()宏

offsetof 是一个宏,它将成员的字节偏移量返回到结构的开头。宏如下所示:

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

它甚至是标准库的一部分(可在 stddef.h 中找到)。

它返回一个名为 MEMBER 的成员的地址,该成员的类型为 TYPE 的结构,从地址 0(恰好是我们正在寻找的偏移量)存储在内存中。

现在我们需要根据我们的原始示例转换这个宏(offsetof(),container_of())。这些宏将取代我们的示例,如下所示。

container_of(&sample1.mem2, struct sample, mem2)||||\/
const char * __mptr = &sample1.mem2;
struct sample * ((char*)  __mptr - &((struct sample*)0)->mem2)||||\/
const char* __mptr = 0x7FFD0D058784;   //(Address of mem2 is 0x7FFD0D058784)
struct sample * (0x7FFD0D058784 - 4)||||\/
struct sample* (0x7FFD0D058780)        //This is the address of the container structure

3、Linux内核的container_of使用

container_of宏在Linux内核中的使用示伪代码例如下:

struct foo {spinlock_t lock;struct workqueue_struct *wq;struct work_struct offload;(...)
};static void foo_work(struct work_struct *work)
{struct foo *foo = container_of(work, struct foo, offload);(...)
}static irqreturn_t foo_handler(int irq, void *arg)
{struct foo *foo = arg;queue_work(foo->wq, &foo->offload);(...)
}static int foo_probe(...)
{struct foo *foo;foo->wq = create_singlethread_workqueue("foo-wq");INIT_WORK(&foo->offload, foo_work);(...)
}
http://www.tj-hxxt.cn/news/33905.html

相关文章:

  • 微信视频网站怎么做河北百度推广
  • 做网站业务的 怎么跑客户官网seo怎么做
  • 教育培训机构有关的网站360seo关键词优化
  • 一级a做爰免费网站互联网推广怎么找渠道
  • 用dw做网站首页推广赚钱项目
  • 中国建设银行官网站哈南分理处活动推广方案
  • 外贸网络营销如何做句容市网站seo优化排名
  • 网站排名易下拉效率网络快速排名优化方法
  • 网站建设注意哪些问题google 优化推广
  • 网站找图片做海报侵权晨阳seo顾问
  • 做网站的需求分析seo搜索引擎优化主要做什么
  • web建立虚拟网站新乡seo外包
  • wordpress快速开发广州seo网站管理
  • 番禺网站建设专家网络推广外包
  • 做网站不买服务器百度能搜到seoul是什么意思中文
  • 如何申请免费的网站北京网站建设公司报价
  • 免费使用模板的网站竞价推广是什么工作
  • 企业网站安全建设方案电商seo搜索优化
  • 网站开发具体问题网站降权查询工具
  • 人人做免费网站品牌策划包括哪几个方面
  • 做网站要多少钱 知乎合肥做网站的公司有哪些
  • 网站seo 规范服务营销论文
  • 宁波专业网站推广制作服务可以发布推广引流的悬赏平台
  • 产品外观设计师什么叫seo网络推广
  • 搭建网站设计吴忠seo
  • 政府类网站设计有什么要点合理使用说明
  • 苏州做网站公司电话seo顾问赚钱吗
  • 网站建设的研发项目厦门百度快照优化排名
  • 网站的主页按钮怎么做软文营销的宗旨是什么
  • 公安门户网站建设中的问题流量宝