在linux下,沒用到的記憶體空間會被拿來當作buffer/cache使用,
以加速I/O存取
所以會感覺記憶體占用很多,
其實實際上如果程式需要記憶體,
就會釋放buffer/cache的空間,所以通常記憶體幾乎都是保持在很高的使用量。
使用free指令,
"-/+ buffers/cache"那一行的free就是實際上系統剩下來沒被其他程式吃掉的記憶體大小
可以用以下的指令取得真實的剩餘空間
echo -n free memory:;free -m | grep buffers/cache | awk '{print $4}'
2009年7月7日 星期二
2009年7月6日 星期一
C陣列與指標
宣告陣列時,
無論是幾維的陣列,
C語言都以分配一塊連續的記憶體空間來處理。
所以這種時候,可以把它當一維陣列處理
C以row為主,假設是二維陣列 arr[2][2]
當一維時的順序就是:
arr[0][0] arr[0][1] arr[1][0] arr[1][1]
雖然指標和陣列用起來差不多,
不過實際上意義是不太一樣的,
可以參考
http://dascan.pixnet.net/blog/post/15600458
http://squall.cs.ntou.edu.tw/cprog/Materials/AdvancedArray.html
要宣告一個指標代表陣列,要用以下的方法:
int data[5][5][5][5];
int (*p)[5][5][5];
可以參考
http://blog.udn.com/cchahacaptain/2197712
無論是幾維的陣列,
C語言都以分配一塊連續的記憶體空間來處理。
所以這種時候,可以把它當一維陣列處理
C以row為主,假設是二維陣列 arr[2][2]
當一維時的順序就是:
arr[0][0] arr[0][1] arr[1][0] arr[1][1]
雖然指標和陣列用起來差不多,
不過實際上意義是不太一樣的,
可以參考
http://dascan.pixnet.net/blog/post/15600458
http://squall.cs.ntou.edu.tw/cprog/Materials/AdvancedArray.html
要宣告一個指標代表陣列,要用以下的方法:
int data[5][5][5][5];
int (*p)[5][5][5];
可以參考
http://blog.udn.com/cchahacaptain/2197712
標籤:
C programming
2009年7月2日 星期四
混合C與C++的程式
參考這個網站的:
http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html在c++的程式內,使用C++標準函式庫,需要標明namespace:
#include <>; //cstdioint main(){...std::printf(...);...}
在c++的程式內,使用C標準函式庫,用法跟c一樣:
#include <> //stdio.hint main(){...printf(...);...}
在c++的程式內,使用C函式庫:
extern "C" {#include "" //my-header.h}int main(){...my_func(...);...}
------------------------------//my-header.h#ifdef __cplusplusextern "C" {#endifmy-function(...);#ifdef __cplusplus}#endif------------------------------//main.cpp#include "" //my-header.hint main(){...my_func(...);...}------------------------------
若不想要include my-header.h,只要使用某幾個c function,可以直接宣告完整的prototype
//main.cpp
extern "C" my_func(int a, int b, int c);
or
//main.cppextern "C" {my_func1(int a, int b, int c);my_func2(int a, int b, int c);my_func3(int a, int b, int c);}
用到時直接用
//main.cpp
my_func1(...);
若要讓c程式call到c的某個function, 使用extern "C"可以使complier將此function給linker的資訊使用c的格式
//my.cppextern "C" my_cpp_func(int a, int b);my_cpp_func(int a, int b){...}
標籤:
C programming
2009年6月28日 星期日
取得浮點數(float)的最大值
其他資料型態應該也可以這樣做...
因為不同平台的資料型態的位元數可能不太一樣,用這個方法比較保險
因為不同平台的資料型態的位元數可能不太一樣,用這個方法比較保險
- include float.h
- use FLT_MAX
標籤:
C programming
2009年6月27日 星期六
2009年6月25日 星期四
C陣列長度取得(用malloc的方法)
當使用動態記憶體配置時
無法使用sizeof的技巧來取得陣列長度
不過可以寫一個自己的malloc和free來計算並維護各個動態分配的長度!!
無法使用sizeof的技巧來取得陣列長度
不過可以寫一個自己的malloc和free來計算並維護各個動態分配的長度!!
- 寫mymalloc在malloc時記錄下這塊記憶體的陣列元素個數
- 寫myfree在free時把記錄下來的對應刪掉
#include
#include
#include
typedef struct arr_sz_t{
void * pointer;
int length;
struct arr_sz_t *next;
}arr_sz;
static arr_sz *sz_mapping;
void* mymalloc(int length, int size);
void myfree(void *p);
void add_sz_entry(void* p, int length);
int arr_length(void* p);
//input 1.array length 2.unit size
void* mymalloc(int length, int size){
void* ret = malloc(length*size);
add_sz_entry(ret, length);
return ret;
}
//free with mapping table
void myfree(void *p){
free(p);
if(sz_mapping != NULL){
arr_sz * t;
t = sz_mapping;
if(t->pointer == p){
sz_mapping = t->next;
free(t);
return;
}
while(t->next != NULL){
arr_sz *next;
next = t->next;
if(next->pointer == p){
t->next = next->next;
free(next);
return;
}
t = t->next;
}
}
}
void add_sz_entry(void* p, int length){
arr_sz* t = (arr_sz *)malloc(sizeof(arr_sz));
t->next = NULL;
t->pointer = p;
t->length = length;
//no sz_mapping
if(sz_mapping == NULL){
sz_mapping = t;
}
//insert
else{
t->next = sz_mapping;
sz_mapping = t;
}
}
//if no mach in mapping table, size is 0
int arr_length(void* p){
//no mapping data
if(sz_mapping == NULL){
return 0;
}
arr_sz* t;
t = sz_mapping;
while(t != NULL){
if(t->pointer == p){
return t->length;
}
t = t->next;
}
return 0;
}
int main(void){
srand(time(0));
int *data[50];
int i;
for(i=0;i<50;i++){
data[i] = (int *)mymalloc(random()%50, sizeof(int));
printf("size of data[%d]: %d\n", i, arr_length(data[i]));
myfree(data[i]);
}
return 0;
}
2009年5月19日 星期二
C的typedef
typedef的功用就是把某些東西變成一個預設的型態(像是int、double、char等型態)來使用
這些東西可以是enum、struct...
char name[20];
int height;
int weight;
};
struct people a;
char name[20];
int height;
int weight;
}People;
People a;
enum week today = Sun;
Week today = Sun
這些東西可以是enum、struct...
- 原本:
char name[20];
int height;
int weight;
};
struct people a;
- 可以寫成
char name[20];
int height;
int weight;
}People;
People a;
- 原本
enum week today = Sun;
- 可以寫成
Week today = Sun
標籤:
C programming
C的enum
實際上enum應該裡面是int,
可以用printf的%d來顯示,
預設的對應就是從數字0開始,
例如enum week{ Sun, Mon, Tue, Wed, Thu, Fri, Sat};
Sun = 0, Mon = 1, Tue = 2, Wed = 3..........................
當然這個對應可以手動指定,像是這樣:
enum week{ Sun=1, Mon, Tue, Wed, Thu, Fri, Sat};
手動指定之後後面若沒有手動指定則會依照手動指定的那一個一直遞增。
Sun = 1, Mon = 2, Tue = 3, Wed = 4.............
要注意有時候手動指定可能會有問題,像是這樣:
enum week{ Sun, Mon, Tue=1, Wed, Thu, Fri, Sat};
Sun = 0, Mon = 1, Tue = 1, Wed = 2.............
====================================================================
enum week today = Sun;
today = Sun;
Week today = Sun
可以用printf的%d來顯示,
預設的對應就是從數字0開始,
例如enum week{ Sun, Mon, Tue, Wed, Thu, Fri, Sat};
Sun = 0, Mon = 1, Tue = 2, Wed = 3..........................
當然這個對應可以手動指定,像是這樣:
enum week{ Sun=1, Mon, Tue, Wed, Thu, Fri, Sat};
手動指定之後後面若沒有手動指定則會依照手動指定的那一個一直遞增。
Sun = 1, Mon = 2, Tue = 3, Wed = 4.............
要注意有時候手動指定可能會有問題,像是這樣:
enum week{ Sun, Mon, Tue=1, Wed, Thu, Fri, Sat};
Sun = 0, Mon = 1, Tue = 1, Wed = 2.............
====================================================================
- 一般用法,宣告一個叫做week的列舉,宣告一個week型態的today且指明是哪一天
enum week today = Sun;
- 在宣告week時可以順便宣告這種型態的變數today
today = Sun;
- 可以使用typedef把enum week定義成Week型態,之後就直接使用Week型態來宣告變數即可,不必每次都再加入enum(簡單來說就是之後都用Week取代enum week)
Week today = Sun
標籤:
C programming
2009年5月5日 星期二
ubuntu內的sh是指到dash
在bin/內
lrwxrwxrwx 1 root root 4 Dec 6 16:29 sh -> dash
dash使用for(( i=0;i<10;i++> ))這種用法會出現
Syntax error: Bad for loop variable
解決方法是:
ps. 使用dash的原因
sudo dpkg-reconfigure dash
lrwxrwxrwx 1 root root 4 Dec 6 16:29 sh -> dash
dash使用for(( i=0;i<10;i++> ))這種用法會出現
Syntax error: Bad for loop variable
解決方法是:
- 使用bash來跑script
bash a.sh - 修改~/.bashrc加入
alias sh='bash'
ps. 使用dash的原因
sudo dpkg-reconfigure dash
The default /bin/sh shell on Debian and Debian-based systems is bash.
However, since the default shell is required to be POSIX-compliant, any shell that conforms to POSIX, such as dash, can serve as /bin/sh.
You may wish to do this because dash is faster and smaller than bash.
2009年4月29日 星期三
FTL介紹
FTL(flash translation layer)是一個轉換的介面,
使得flash 能夠被當作一般的儲存裝置使用(因為他不能直接更新檔案內容)
主要的作用有:
上面的page 和block大小只是個範例,實際上有的會不一樣(例如page為4K之類)
FTL位址轉換對應基本上最簡單的可以分成兩種:
像是已知的NFTL或是Log buffer-based FTL schemes之類
使得flash 能夠被當作一般的儲存裝置使用(因為他不能直接更新檔案內容)
主要的作用有:
- 位址轉換,把LBA(logical block address)轉換成flash上的位址
- garbage collection(GC),由於flash的out-of-place update的關係,會造成有一些page被invalid掉,所以需要回收這些page
上面的page 和block大小只是個範例,實際上有的會不一樣(例如page為4K之類)
FTL位址轉換對應基本上最簡單的可以分成兩種:
- page level - 對應比較細,但占用較大的轉換表(非常之大......)
- block level - 對應比較粗躁,在GC的overhead很大(因為只要修改一個page就要重寫整個block),但是節省轉換表
像是已知的NFTL或是Log buffer-based FTL schemes之類
2009年4月23日 星期四
linux share memory用法
http://www.ecst.csuchico.edu/~beej/guide/ipc/shmem.html
可以用man 2 shmget查詢相關資料
需要include
主要有四個function:
int shmget(key_t key, size_t size, int shmflg);
若要移除已經建立的share memory,須使用shmctl:
先拿到shmid之後,用shmctl即可移除
shmctl(shmid,IPC_RMID,0);
可以用man 2 shmget查詢相關資料
需要include
sys/shm.h
主要有四個function:
- shmget() - 建立共享記憶體
- shmat() - attach 共享記憶體
- shmdt() - detach 共享記憶體
- shmctl() - 設定共享記憶體
int shmget(key_t key, size_t size, int shmflg);
- key可以這樣用:(key_t)1234
- size:以byte為單位的大小
- shmflag:
IPC_CREATE | 0666
(0666是權限) - 若shmflag內有IPC_EXCL 則表示:
若之前用同一個key建立過share memory,則此次建立會失敗(防止用到已創立過的)
若沒用這flag就會連接到同一個地方 - 回傳值是shmid,錯誤時則會回傳-1
- attach會把個shmid的share memory的位址放到shmaddr
- 若失敗則shmaddr為-1
- detach
若要移除已經建立的share memory,須使用shmctl:
先拿到shmid之後,用shmctl即可移除
shmctl(shmid,IPC_RMID,0);
寫出我的簡單範例做講解...
#include
#include
int main(int argc, char* argv[]){
int data[100];
int shmid;
void *shared_memory = (void *)0;
shmid =
shmget ((key_t) 123, sizeof (int) * 100, 0666 | IPC_CREAT);
if (shmid == -1)
{
fprintf (stderr, "shmget failed\n");
exit (1);
}
shared_memory = shmat (shmid, (void *)0, 0);
if (shared_memory == (void *)-1)
{
fprintf (stderr, "shmat failed\n");
exit (1);
}
printf ("Memory attached at %X\n", shared_memory);
if(argc == 2 && strcmp(argv[1], "-d") == 0){
printf("reset data to 0!\n");
((int *)shared_memory)[0] = 0;
}
printf("old data:%d\n", ((int *)shared_memory)[0]++);
printf("new data:%d\n", ((int *)shared_memory)[0]);
exit(0);
}
2009年2月24日 星期二
ubuntu style kernel install
1.install:
build-essential
make-kernels
libncurse
build-essential
make-kernels
libncurse
linux-header
linux-source
2.make menuconfig
3.make-kpkg clean
4.make-kpkg --initrd kernel_image kernel_headers
5.sudo dpkg -i linux-image-<source version>_<source
version>-10.00.Custom_i386.deb linux-headers-<source version>_<source
version>-10.00.Custom_i386.deb
標籤:
linux kernel
2009年1月21日 星期三
Fwd: linux核心編譯,增加新核心
詳情參考鳥哥
http://linux.vbird.org/linux_basic/0540kernel.php
1.取得原始碼
kernel.org
2.設定
$ make menuconfig
最好載入目前設定(/boot/config......)再修改
3.編譯
$ make
4.安裝模組
$ make modules_install
會安裝到/lib/modules/核心版本/
(所以如果編跟本來同版本的話會用到同一個資料夾 最好備份原來的)
5.核心檔案放在:
原始碼/arch/i386/boot/bzImage
複製到/boot/內以供開機使用
檔名最好改成"vmlinux_核心版本"以供辨認
6.建立initrd(Initial RAM Disk)
initrd 可以將 /lib/modules/.... 內的『開機過程當中一定需要的模組』包成一個檔案
確保可以順利掛載root,這樣其他的module就可以在/lib/modules/裡找到了
$ mkinitrd initrd_`uname -r` `uname -r`
會產生檔名為initrd_`uname -r`.EL的檔案
(不一定要`uname -r`,自己取名,因為通常要做的版本跟自己現在用的不一樣)
7.複製system.map
$ cp 原始碼/System.map /boot/System.map.版本號
這樣才不會稿混
8.修改grub
$ vi /boot/grub/menu.lst
複製一份本來可以用的
然後改一下設定
把initrd和kernel的檔案改成新編好的
9.reboot & try it
http://linux.vbird.org/linux_basic/0540kernel.php
1.取得原始碼
kernel.org
2.設定
$ make menuconfig
最好載入目前設定(/boot/config......)再修改
3.編譯
$ make
4.安裝模組
$ make modules_install
會安裝到/lib/modules/核心版本/
(所以如果編跟本來同版本的話會用到同一個資料夾 最好備份原來的)
5.核心檔案放在:
原始碼/arch/i386/boot/bzImage
複製到/boot/內以供開機使用
檔名最好改成"vmlinux_核心版本"以供辨認
6.建立initrd(Initial RAM Disk)
initrd 可以將 /lib/modules/.... 內的『開機過程當中一定需要的模組』包成一個檔案
確保可以順利掛載root,這樣其他的module就可以在/lib/modules/裡找到了
$ mkinitrd initrd_`uname -r` `uname -r`
會產生檔名為initrd_`uname -r`.EL的檔案
(不一定要`uname -r`,自己取名,因為通常要做的版本跟自己現在用的不一樣)
7.複製system.map
$ cp 原始碼/System.map /boot/System.map.版本號
這樣才不會稿混
8.修改grub
$ vi /boot/grub/menu.lst
複製一份本來可以用的
然後改一下設定
把initrd和kernel的檔案改成新編好的
9.reboot & try it
標籤:
linux kernel
訂閱:
文章 (Atom)