目錄
寫在前面
頻繁使用系統調用的例子
減少系統調用的次數的例子
不使用系統調用的例子
參考文獻
寫在前面
歡迎各位網友對本博文提出意見,如需轉載請注明出處。
下面我就開門見山的說吧,使用系統調用(例如open()、read()、write()等函數)會影響系統的性能。
與函數調用相比,系統調用的開銷要大一些,因為在執行系統調用時,Linux必須從運行用戶代碼切換到執行內核代碼,然後再返回用戶代碼。
減少這種開銷的一個好辦法是,在程序中盡量減少系統調用的次數,並且讓每次系統調用完成盡可能多的工作。
下面我們通過幾個簡單的栗子來說明一下為什麼會這樣。
頻繁使用系統調用的例子
這是一個關於文件復制的程序,看起來非常的簡單,我們首先使用系統調用來完成文件復制的操作,為了體現頻繁的系統調用,程序中將每次讀寫的數據塊大小設為1byte,被復制的文件大小為1M。
[code]/*copy_system1.c*/
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
int main()
{
char c;
int in, out;
in = open("file.in", O_RDONLY);
out = open("file.out", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
while (read(in, &c, 1) == 1)
{
write(out, &c, 1);
}
return 0;
}
通過這種方式運行這個程序,
[code]TIMEFORMAT"" time ./copy_system
你會得到這樣的輸出結果:
4.33user 6.08system 0:10.42elapsed 99%CPU (0avgtext+0avgdata 412maxresident)k
0inputs+2048outputs (0major+145minor)pagefaults 0swaps
從這個結果中,我們不難發現程序運行了10s左右,而且CPU占有率高達99%,足見其效率低下。
NOTE:這個程序在運行之前你要准備一個大約1M的文件file.in,你可以用這個
程序來生成你想要的這個文件。
減少系統調用的次數的例子
下面我們改變數據塊的大小,再來測試一下,這樣做可以減少系統調用的次數,下面是這個程序:
[code]/*copy_system2.c*/
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
int main()
{
char block[1024];
int in, out;
int nread;
in = open("file.in", O_RDONLY);
out = open("file.out", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
while (nread = read(in, block, 1024) > 0)
{
write(out, block, nread);
}
return 0;
}
同樣使用下面的命令來運行:
[code]TIMEFORMAT="" time ./copy_system2
0.01user 0.01system 0:00.02elapsed 92%CPU (0avgtext+0avgdata 408maxresident)k
0inputs+8outputs (0major+145minor)pagefaults 0swaps
結果很明顯,這次執行只花費了0.02s,而且CPU占有率也降低到了92%。現在你看到了頻繁系統調用的後果了吧。
不使用系統調用的例子
為了體現不使用系統調用的優勢,我麼再來寫一個不使用系統調用的程序。
[code]#include <stdio.h>
#include <stdlib.h>
int main()
{
int c;
FILE *in, *out;
in = fopen("file.in", "r");
out = fopen("file.out", "w");
while ((c = fgetc(in)) != EOF)
{
fputc(c, out);
}
return 0;
}
我們依然使用這個命令進行測試:
[code]TIMEFORMAT="" time ./copy_system3
0.05user 0.01system 0:00.12elapsed 55%CPU (0avgtext+0avgdata 500maxresident)k
4128inputs+4096outputs (0major+167minor)pagefaults 0swaps
現在結果很明顯,這個程序只花費了0.12s,而且CPU占有率僅為55%,說明不使用系統調用的程序運行起來效率明顯高於使用系統調用的程序。
| 程序 | 是否系統調用 | 數據塊大小(byte) | 所用時間(s) | CPU占有率 | copy_system1是110.4299%copy_system2是10240.0295%copy_system3否10.1255%
NOTE:這三個程序都是對大小為1M的文件進行復制。
通過上面這個表格,我們很容易得出這樣的結論:
系統調用會導致程序效率低下(程序1與程序3做對比)
頻繁系統調用更會導致程序效率低下(程序1與程序2做對比)
由此,我們可以得出提高程序效率的方法:
盡量避免頻繁使用系統調用;
如果不可避免的使用了系統調用,那麼就充分利用這次系統調用,讓它完成盡可能多的工作。
參考文獻
[1] Neil Matthew Richard Stones. Linux 程序設計(第四版). 人民郵電出版社