詳解Linux核心中的container of函式

2022-09-26 16:24:22 字數 1642 閱讀 7399

前言

www.cppcns.com在linux 核心中,container_of函式使用非常廣,例如 linux核心鍊錶list_head、工作佇列work_struct中。

在linux核心中大名鼎鼎的巨集container_of(),其實它的語法很簡單,只是一些指標的靈活應用,它分兩步:

第一步,首先定義乙個臨時的資料型別(通過typeof( ((type *)0)->member)獲得)與ptr相同的指標變數__mptr,然後用它來儲存ptr的值。

第二步,用(char *)__mptr減去member在結構體中的偏移量,得到的值就是整個結構體變數的首位址(整個巨集的返回值就是這個首位址)。

那這個巨集到底是用來幹嘛的呢?我們先來看看它在核心中是怎樣定義的。

呵呵,乍一看不知道是什麼東東。

我們先來分析一下container_of(ptr,type,member),這裡面有ptr,type,member分別代表指標、型別、成員。

看乙個例子:

struct test

; struct test temp;

現在呢如果我想通過temp.j的位址找到temp的首位址就可以使用container_of(&temp.j,struct test,j);

現在我們知道container_of()的作用就是通過乙個結構變數中乙個成員的位址找到這個結構體變數的首位址。

下面來看看比較複雜的內容:

我們用上面的struct test張展一下

const typeof(((struct test *)0)->j) * __mptr = (&temp.j); //(sturct test *)0 表示資料段基址

其中,typeof是gnu程式設計客棧 c對標準c的擴充套件,它的作用是根據變數獲取變數的型別。因此,上述**的作用是首先使用typeof獲取結構體成員j的型別為int,然後頂乙個int指標型別的臨時變數__mptr,並將結構體變數中的成員的位址賦給臨時變數__mptr。

(struct test *)((char *)__mptr - offsetof(struct test,j));

接著我們來看一下offsetof(struct test,j),他在核心中如下定義

展開(size_t)&((struct test *)0)->j,這是什麼東東?

一開始也不明白,這裡要感謝曹忠明老師的熱心幫助,一語驚醒夢中人,呵呵,可以是這樣理解。

其中size_t是整型,那麼我們可以知道最終的結果是乙個整形值,也就是j相對於0位址的偏移量。也許現在你會問,整出這麼個玩意幹嘛,下面看個列子:

程式執行結果:

發現沒有如果把第二個值 減去最後乙個值,就能得到第乙個值。

在回首一下它:

(struct test *)((char *)__mpkmyiglzxymtr - offsetof(struct test,j));

是不是可以獲得結構體變數temp的首位址呀,是不是太精妙了呀

總結linux核心中隨隨便便乙個巨集就有如此精妙,想想對linux了解非常多的牛人,還有很www.cppcns.com長一段路。好了,以上就是本文的全部內容了,希望這篇文章的內容對大家的工作和學習能有所幫助,如果有疑問可以留言交流,謝謝大家對我們的支援。

本文標題: 詳解linux核心中的container_of函式

本文位址: /os/linux/161782.html

核心中的kmalloc函式詳解

一 kmalloc函式詳解 include void kmalloc size t size,int flags 給 kmalloc 的第乙個引數是要分配的塊的大小.第 2 個引數,分配標誌,非常有趣,因為它以幾個方式控制 kmalloc 的行為.最一般使用的標誌,gfp kernel,意思是這個分...

核心中的kmalloc函式詳解

一 kmalloc函式詳解 include void kmalloc size t size,int flags 給 kmalloc 的第乙個引數是要分配的塊的大小.第 2 個引數,分配標誌,非常有趣,因為它以幾個方式控制 kmalloc 的行為.最一般使用的標誌,gfp kernel,意思是這個分...

核心中的kmalloc函式詳解

一 kmalloc函式詳解 include void kmalloc size t size,int flags 給 kmalloc 的第乙個引數是要分配的塊的大小.第 2 個引數,分配標誌,非常有趣,因為它以幾個方式控制 kmalloc 的行為.最一般使用的標誌,gfp kernel,意思是這個分...