之前的文章提及過開源C語言庫Melon的函數模板。使用函數模板來擴展函數功能。
今天,我們介紹Melon中的span組件,使用它來輕鬆監控函數的調用耗時情況。
概述
Melon中的資源開銷(span)組件是用來測量C語言函數開銷的,這個模塊需要配合函數模板模塊一同使用,因此也需要定義MLN_FUNC_FLAG才會使得函數模板功能啓用,進而實現函數開銷的跟蹤。
目前支持的開銷如下:
- 時間開銷
頭文件
#include "mln_span.h"
模塊名
span
在Melon中支持模塊選擇性編譯,因此可以選擇指定的模塊進行編譯,腳本將自行計算該模塊所依賴的Melon中的其他模塊並一同進行編譯。
示例
下面我們一起看一個多線程的示例,用來展示mln_span接口的使用以及在多線程環境下的效果。
//a.c
#include <pthread.h>
#include "mln_span.h"
#include "mln_func.h"
MLN_FUNC(int, abc, (int a, int b), (a, b), {
return a + b;
})
MLN_FUNC(static int, bcd, (int a, int b), (a, b), {
return abc(a, b) + abc(a, b);
})
MLN_FUNC(static int, cde, (int a, int b), (a, b), {
return bcd(a, b) + bcd(a, b);
})
void *pentry(void *args)
{
int i;
mln_span_start();
for (i = 0; i < 10; ++i) {
cde(i, i + 1);
}
mln_span_stop();
mln_span_dump();
mln_span_release();
return NULL;
}
int main(void)
{
int i;
pthread_t pth;
pthread_create(&pth, NULL, pentry, NULL);
for (i = 0; i < 10; ++i) {
bcd(i, i + 1);
}
pthread_join(pth, NULL);
return 0;
}
前面我們説過,span組件需要配合函數模板組件一同使用。這裏我們使用函數模板組件定義了三個函數abc, bcd, cde。
然後我們在main函數中啓動一個線程,並在線程入口函數內,調用mln_span_start開啓資源消耗跟蹤。然後調用cde函數十次。而在main函數中,在創建線程後,循環調用bcd函數十次,最後等待線程退出,程序結束。
我們對這段程序進行編譯:
cc -o a a.c -I /usr/local/melon/include/ -L /usr/local/melon/lib/ -lmelon -DMLN_FUNC_FLAG -lpthread
注意,這裏-DMLN_FUNC_FLAG是用來啓用函數模板模塊的功能。如果不定義這個宏,那麼使用MLN_FUNC定義的函數就是普通C語言函數,不會啓用任何跟蹤能力。
編譯好後運行程序,可以看到類似如下的輸出:
| pentry at a.c:20 takes 92 (us)
| cde at a.c:13 takes 4 (us)
| bcd at a.c:9 takes 1 (us)
| abc at a.c:5 takes 0 (us)
| abc at a.c:5 takes 0 (us)
| bcd at a.c:9 takes 1 (us)
| abc at a.c:5 takes 0 (us)
| abc at a.c:5 takes 0 (us)
| cde at a.c:13 takes 5 (us)
| bcd at a.c:9 takes 0 (us)
| abc at a.c:5 takes 0 (us)
| abc at a.c:5 takes 0 (us)
| bcd at a.c:9 takes 2 (us)
| abc at a.c:5 takes 0 (us)
| abc at a.c:5 takes 0 (us)
| cde at a.c:13 takes 24 (us)
| bcd at a.c:9 takes 1 (us)
| abc at a.c:5 takes 0 (us)
| abc at a.c:5 takes 0 (us)
| bcd at a.c:9 takes 21 (us)
| abc at a.c:5 takes 0 (us)
| abc at a.c:5 takes 0 (us)
| cde at a.c:13 takes 5 (us)
| bcd at a.c:9 takes 1 (us)
| abc at a.c:5 takes 0 (us)
| abc at a.c:5 takes 0 (us)
| bcd at a.c:9 takes 1 (us)
| abc at a.c:5 takes 0 (us)
| abc at a.c:5 takes 0 (us)
| cde at a.c:13 takes 3 (us)
| bcd at a.c:9 takes 2 (us)
| abc at a.c:5 takes 0 (us)
| abc at a.c:5 takes 0 (us)
| bcd at a.c:9 takes 1 (us)
| abc at a.c:5 takes 0 (us)
| abc at a.c:5 takes 0 (us)
| cde at a.c:13 takes 30 (us)
| bcd at a.c:9 takes 24 (us)
| abc at a.c:5 takes 0 (us)
| abc at a.c:5 takes 1 (us)
| bcd at a.c:9 takes 6 (us)
| abc at a.c:5 takes 0 (us)
| abc at a.c:5 takes 0 (us)
| cde at a.c:13 takes 3 (us)
| bcd at a.c:9 takes 2 (us)
| abc at a.c:5 takes 0 (us)
| abc at a.c:5 takes 0 (us)
| bcd at a.c:9 takes 1 (us)
| abc at a.c:5 takes 0 (us)
| abc at a.c:5 takes 0 (us)
| cde at a.c:13 takes 3 (us)
| bcd at a.c:9 takes 2 (us)
| abc at a.c:5 takes 0 (us)
| abc at a.c:5 takes 1 (us)
| bcd at a.c:9 takes 1 (us)
| abc at a.c:5 takes 0 (us)
| abc at a.c:5 takes 0 (us)
| cde at a.c:13 takes 7 (us)
| bcd at a.c:9 takes 1 (us)
| abc at a.c:5 takes 0 (us)
| abc at a.c:5 takes 0 (us)
| bcd at a.c:9 takes 2 (us)
| abc at a.c:5 takes 0 (us)
| abc at a.c:5 takes 1 (us)
| cde at a.c:13 takes 3 (us)
| bcd at a.c:9 takes 2 (us)
| abc at a.c:5 takes 1 (us)
| abc at a.c:5 takes 0 (us)
| bcd at a.c:9 takes 0 (us)
| abc at a.c:5 takes 0 (us)
| abc at a.c:5 takes 0 (us)
最後
感興趣的小夥伴歡迎訪問Melon的Github進行試用。Melon是一個跨平台的C語言庫,內含多種數據結構、算法和常用組件。Melon並不是一個純粹的數據結構和算法庫,而是致力於提供開發中常用的組件,如:內存池、線程池、多進程框架、可觀測性等。Melon提供中英文文檔,內含各模塊接口説明和示例代碼,便於開發者快速上手。
感謝閲讀!