訂閱
糾錯(cuò)
加入自媒體

Linux應(yīng)用程序設(shè)計(jì):如何獲取線程棧的使用信息?

面對(duì)的問(wèn)題

對(duì)于線程的?臻g,相信各位小伙伴都不陌生。它有下面的這幾項(xiàng)特性:

由操作系統(tǒng)分配固定的空間;

使用一個(gè)棧寄存器來(lái)保存實(shí)時(shí)位置;

后進(jìn)先出。

今天,我們不聊操作系統(tǒng)層面對(duì)棧的管理,只從應(yīng)用程序的角度,來(lái)看一下如何實(shí)時(shí)獲取棧的使用情況。

在一般的單片機(jī)/嵌入式程序開(kāi)發(fā)過(guò)程中,在創(chuàng)建一個(gè)線程(或者稱作任務(wù))的時(shí)候,是可以指定給該線程分配多少?臻g的。

然后在調(diào)試的時(shí)候呢,周期性的打印出棧區(qū)的使用情況:消耗了多少空間,還剩余多少空間。

這樣的話,跑完每一個(gè)測(cè)試用例之后,就能得到一個(gè)大致的統(tǒng)計(jì)數(shù)據(jù),從而最終決定:需要給這個(gè)線程分配多少?臻g。

例如:在 ucOS 系統(tǒng)中,提供了函數(shù) NT8U OSTaskStkChk(INT8U prio, OS_STK_DATA  *p_stk_data),來(lái)獲取一個(gè)任務(wù)的棧使用信息。

但是在 Linux 系統(tǒng)中,并沒(méi)有這樣類似的函數(shù),來(lái)直接獲取棧使用信息。

因此,為了得到此線程的已使用和空閑?臻g,必須通過(guò)其他的方式來(lái)獲取。

下面,就提供 2 種解決方案:正規(guī)軍方式和雜牌軍方式!

正規(guī)軍方式

在 Linux 系統(tǒng)中,在創(chuàng)建一個(gè)線程的時(shí)候,是可以通過(guò)線程屬性來(lái)設(shè)置:為這個(gè)線程分配多少的棧(stack)空間的。

如果應(yīng)用程序不指定的話,操作系統(tǒng)就設(shè)置為一個(gè)默認(rèn)的值。

線程創(chuàng)建完畢之后,操作系統(tǒng)在內(nèi)核空間,記錄了這個(gè)線程的一切信息,當(dāng)然也就包括給它分配的棧空間信息。

為了讓?xiě)?yīng)用層能夠獲取到這個(gè)信息,操作系統(tǒng)也提供了相應(yīng)的系統(tǒng)函數(shù)。代碼如下:

pthread_attr_t attr;
void *stack_addr;
int stack_size;
memset(&attr, 0, sizeof(pthread_attr_t));
pthread_getattr_np(pthread_self(), &attr);
pthread_attr_getstack(&attr, &stack_addr, &stack_size);
pthread_attr_destroy(&attr);
printf("statck top   = %p ", stack_addr);
printf("stack bottom = %p ", stack_addr + stack_size);

從上面這段代碼中可以看到,它只能獲取?臻g的地址開(kāi)始以及總的空間大小,仍然不知道當(dāng)前棧空間的實(shí)際使用情況!

我找了一下相關(guān)的系統(tǒng)調(diào)用,Linux 似乎沒(méi)有提供相關(guān)的函數(shù)。

怎么辦?只能迂回操作。

我們知道,在 Linux x86 平臺(tái)上,寄存器 ESP 就是來(lái)存儲(chǔ)棧指針的。對(duì)于一個(gè)滿遞減類型的棧,這個(gè)寄存器里的值,就代表了當(dāng)前棧中最后背使用的、那個(gè)?臻g的地址。

因此,只要我們能夠獲取到 ESP 寄存器里的值,就相當(dāng)于知道了當(dāng)前這個(gè)棧有多少空間被使用了。

那么怎樣來(lái)獲取 ESP 寄存器的值呢?既然是寄存器,那就肯定是使用匯編代碼了。

很簡(jiǎn)單,就 1 行:

size_t esp_val;
asm("movl %%esp, %0" : "=m"(esp_val) :);

對(duì)不起,我錯(cuò)了!應(yīng)該是 2 行代碼,忘記變量定義了。

對(duì)于匯編代碼不熟悉的小伙伴,可以參考之前總結(jié)的一篇文章:內(nèi)聯(lián)匯編很可怕嗎?看完這篇文章,終結(jié)它!

找到第 4 個(gè)示例,直接抄過(guò)來(lái)就行。

好了,拿到了以上的所有信息,就可以計(jì)算出棧的已使用和空閑空間的大小了:

1  2  下一頁(yè)>  
聲明: 本文由入駐維科號(hào)的作者撰寫(xiě),觀點(diǎn)僅代表作者本人,不代表OFweek立場(chǎng)。如有侵權(quán)或其他問(wèn)題,請(qǐng)聯(lián)系舉報(bào)。

發(fā)表評(píng)論

0條評(píng)論,0人參與

請(qǐng)輸入評(píng)論內(nèi)容...

請(qǐng)輸入評(píng)論/評(píng)論長(zhǎng)度6~500個(gè)字

您提交的評(píng)論過(guò)于頻繁,請(qǐng)輸入驗(yàn)證碼繼續(xù)

  • 看不清,點(diǎn)擊換一張  刷新

暫無(wú)評(píng)論

暫無(wú)評(píng)論

人工智能 獵頭職位 更多
掃碼關(guān)注公眾號(hào)
OFweek人工智能網(wǎng)
獲取更多精彩內(nèi)容
文章糾錯(cuò)
x
*文字標(biāo)題:
*糾錯(cuò)內(nèi)容:
聯(lián)系郵箱:
*驗(yàn) 證 碼:

粵公網(wǎng)安備 44030502002758號(hào)