1. 程式人生 > >對於linux下system()函式的深度理解(轉載)

對於linux下system()函式的深度理解(轉載)

轉載自 http://blog.sina.com.cn/s/blog_8043547601017qk0.html
這幾天調程式(嵌入式linux),發現程式有時就莫名其妙的死掉,每次都定位在程式中不同的system()函式,直接在shell下輸入system()函式中呼叫的命令也都一切正常.就沒理這個bug,以為是其他的程式碼影響到這個,或是核心驅動檔案系統什麼的異常導致,昨天有出現了這個問題,就隨手百了一下度,問題出現了,很多人都說system()函式要慎用要少用要能不用則不用,system()函式不穩定?
下面對system函式做一個簡單的介紹:
標頭檔案
#i nclude
定義函式
int system(const char * string);
函式說明
system()會呼叫fork()產生子程序,由子程序來呼叫/bin/sh-c string來執行引數string字串所代表的命令,此命>令執行完後隨即返回原呼叫的程序。在呼叫system()期間SIGCHLD 訊號會被暫時擱置,SIGINT和SIGQUIT 訊號則會被忽略。 返回值 =-1:出現錯誤 =0:呼叫成功但是沒有出現子程序 >0:成功退出的子程序的id 如果system()在呼叫/bin/sh時失敗則返回127,其他失敗原因返回-1。若引數string為空指標(NULL),則返回非零值>。如果system()呼叫成功則最後會返回執行shell命令後的返回值,但是此返回值也有可能為 system()呼叫/bin/sh失敗所返回的127,因此最好能再檢查errno 來確認執行成功。
附加說明
在編寫具有SUID/SGID許可權的程式時請勿使用system(),system()會繼承環境變數,通過環境變數可能會造成系統安全的問題。 system函式已經被收錄在標準c庫中,可以直接呼叫,使用system()函式呼叫系統命令的基本使用方法如下:

include

int main()
{
system(“mkdir HOME/.SmartPlatform/);system(mkdirHOME/.SmartPlatform/Files/”);
system(“cp mainnew.cpp $HOME/.SmartPlatform/Files/”);
return 0;
}
下面我們來看看system函式的原始碼:

include #include #include #include

int system(const char * cmdstring)
{
pid_t pid;
int status;
if(cmdstring == NULL)
{
return (1);
}
if((pid = fork())<0)
{
status = -1;
}
else if(pid = 0)
{
execl(“/bin/sh”, “sh”, “-c”, cmdstring, (char *)0); -exit(127); //子程序正常執行則不會執行此語句 }
else
{
while(waitpid(pid, &status, 0) < 0)
{
if(errno != EINTER){ status = -1; break;
}
}
}
return status;
}
花了兩天時間仔細研究了一下,在網上發現了一篇精品部落格,介紹的很詳細了,謝謝博主,直接轉, 原文如下:

http://my.oschina.net/renhc/blog/53580
【C/C++】Linux下使用system()函式一定要謹慎
曾經的曾經,被system()函式折磨過,之所以這樣,是因為對system()函數了解不夠深入。只是簡單的知道用這個函式執行一個系統命令,這遠遠不夠,它的返回值、它所執行命令的返回值以及命令執行失敗原因如何定位,這才是重點。當初因為這個函式風險較多,故拋棄不用,改用其他的方法。這裡先不說我用了什麼方法,這裡必須要搞懂system()函式,因為還是有很多人用了system()函式,有時你不得不面對它。
先來看一下system()函式的簡單介紹:

include

int system(const char *command);
system() executes a command specified in command by calling /bin/sh -c command, and returns after the command has been completed. During execution of the command, SIGCHLD will be blocked, and SIGINT and SIGQUIT will be ignored. system()函式呼叫/bin/sh來執行引數指定的命令,/bin/sh 一般是一個軟連線,指向某個具體的shell,比如bash,-c選項是告訴shell從字串command中讀取命令; 在該command執行期間,SIGCHLD是被阻塞的,好比在說:hi,核心,這會不要給我送SIGCHLD訊號,等我忙完再說; 在該command執行期間,SIGINT和SIGQUIT是被忽略的,意思是程序收到這兩個訊號後沒有任何動作。
再來看一下system()函式返回值:
The value returned is -1 on error (e.g. fork(2) failed), and the return status of the command otherwise. This latter return status is in the format specified in wait(2). Thus, the exit code of the command will be WEXITSTATUS(status). In case /bin/sh could not be executed, the exit status will be that of a command that does exit(127). If the value of command is NULL, system() returns nonzero if the shell is available, and zero if not.
為了更好的理解system()函式返回值,需要了解其執行過程,實際上system()函式執行了三步操作:
1.fork一個子程序;
2.在子程序中呼叫exec函式去執行command;
3.在父程序中呼叫wait去等待子程序結束。 對於fork失敗,system()函式返回-1。 如果exec執行成功,也即command順利執行完畢,則返回command通過exit或return返回的值。 (注意,command順利執行不代表執行成功,比如command:”rm debuglog.txt”,不管檔案存不存在該command都順利執行了) 如果exec執行失敗,也即command沒有順利執行,比如被訊號中斷,或者command命令根本不存在,system()函式返回127. 如果command為NULL,則system()函式返回非0值,一般為1.
看一下system()函式的原始碼
看完這些,
我想肯定有人對system()函式返回值還是不清楚,看原始碼最清楚,下面給出一個system()函式的實現:
int system(const char * cmdstring)
{
pid_t pid;
int status;
if(cmdstring == NULL)
{
return (1); //如果cmdstring為空,返回非零值,一般為1
}
if((pid = fork())<0)
{
status = -1; //fork失敗,返回-1
}
else if(pid == 0)
{
execl(“/bin/sh”, “sh”, “-c”, cmdstring, (char *)0);
_exit(127); // exec執行失敗返回127,注意exec只在失敗時才返回現在的程序,成功的話現在的程序就不存在啦~~
}
else //父程序
{
while(waitpid(pid, &status, 0) < 0)
{
if(errno != EINTR)
{
status = -1; //如果waitpid被訊號中斷,則返回-1
break;
}
}
}
return status; //如果waitpid成功,則返回子程序的返回狀態
}

仔細看完這個system()函式的簡單實現,那麼該函式的返回值就清晰了吧,那麼什麼時候system()函式返回0呢?只在command命令返回0時。 看一下該怎麼監控system()函式執行狀態 這裡給我出的做法:
int status;
if(NULL == cmdstring) //如果cmdstring為空趁早閃退吧,儘管system()函式也能處理空指標
{
return XXX;
}
status = system(cmdstring);
if(status < 0)
{
printf(“cmd: %s\t error: %s”, cmdstring, strerror(errno)); // 這裡務必要把errno資訊輸出或記入Log
return XXX;
}

if(WIFEXITED(status))
{
printf(“normal termination, exit status = %d\n”, WEXITSTATUS(status)); //取得cmdstring執行結果 }
else if(WIFSIGNALED(status))
{
printf(“abnormal termination,signal number =%d\n”, WTERMSIG(status)); //如果cmdstring被訊號中斷,取得訊號值
}
else if(WIFSTOPPED(status))
{
printf(“process stopped, signal number =%d\n”, WSTOPSIG(status)); //如果cmdstring被訊號暫停執行,取得訊號值
}

至於取得子程序返回值的相關介紹可以參考另一篇文章:http://my.oschina.net/renhc/blog/35116 system()函式用起來很容易出錯,返回值太多,而且返回值很容易跟command的返回值混淆。
這裡推薦使用popen()函式替代,關於popen()函式的簡單使用也可以通過上面的連結檢視。
popen()函式較於system()函式的優勢在於使用簡單,popen()函式只返回兩個值: 成功返回子程序的status,使用WIFEXITED相關巨集就可以取得command的返回結果; 失敗返回-1,我們可以使用perro()函式或strerror()函式得到有用的錯誤資訊。 這篇文章只涉及了system()函式的簡單使用,還沒有談及SIGCHLD、SIGINT和SIGQUIT對system()函式的影響,事實上,之所以今天寫這篇文章,是因為專案中因有人使用了system()函式而造成了很嚴重的事故。現像是system()函式執行時會產生一個錯誤:“No child processes”。 關於這個錯誤的分析,感興趣的朋友可以看一下:http://my.oschina.net/renhc/blog/54582 2012-04-14
[email protected] 轉載請註明出處。

下面是第二篇,對於system()函式的錯誤詳細分析,再次感謝博主
【C/C++】Linux下system()函式引發的錯誤
今天,一個運行了近一年的程式突然掛掉了,問題定位到是system()函數出的問題,關於該函式的簡單使用在我上篇文章做過介紹: http://my.oschina.net/renhc/blog/53580
先看一下問題 簡單封裝了一下system()函式:
int pox_system(const char *cmd_line)
{
return system(cmd_line);
}
函式呼叫:
int ret = 0;
ret = pox_system(“gzip -c /var/opt/I00005.xml > /var/opt/I00005.z”);
if(0 != ret)
{
Log(“zip file failed\n”);
}
問題現象:每次執行到此處,都會zip failed。而單獨把該命令拿出來在shell裡執行卻總是對的,事實上該段程式碼已運行了很長時間,從沒出過問題。
糟糕的日誌
分析log時,我們只能看到“zip file failed”這個我們自定義的資訊,至於為什麼fail,毫無線索。 那好,我們先試著找出更多的線索:
int ret = 0;
ret = pox_system(“gzip -c /var/opt/I00005.xml > /var/opt/I00005.z”);
if(0 != ret)
{
Log(“zip file failed: %s\n”, strerror(errno)); //嘗試打印出系統錯誤資訊
}
我們增加了log,通過system()函式設定的errno,我們得到一個非常有用的線索:system()函式失敗是由於“ No child processes”。繼續找Root Cause。
誰動了errno
我們通過上面的線索,知道system()函式設定了errno為ECHILD,然而從system()函式的man手冊裡我們找不到任何有關EHILD的資訊。我們知道system()函式執行過程為:fork()->exec()->waitpid(). 很顯然waitpid()有重大嫌疑,我們去查一下man手冊,看該函式有沒有可能設定
ECHILD: ECHILD (for waitpid() or waitid()) The process specified by pid (waitpid()) or idtype and id (waitid()) does not exist or is not a child of the calling process. (This can happen for one’s own child if the action for SIGCHLD is set to SIG_IGN. See also the Linux Notes section about threads.)
果然有料,如果SIGCHLD訊號行為被設定為SIG_IGN時,waitpid()函式有可能因為找不到子程序而報ECHILD錯誤。似乎我們找到了問題的解決方案:在呼叫system()函式前重新設定SIGCHLD訊號為預設值,即signal(SIGCHLD, SIG_DFL)。
我們很興奮,暫時顧不上看Linux Notes部分,直接加上程式碼測試!乖乖,問題解決了!
如此處理問題是你的風格嗎 正當我們急於check in 程式碼時,一個疑問出現了:“這個錯誤為什麼以前沒發生”?是啊,執行良好的程式怎麼突然就掛了呢?首先我們程式碼沒有改動,那麼肯定是外部因素了。一想到外部因素,我們開始抱怨:“肯定是其他組的程式影響我們了!”但抱怨這是沒用的,如果你這麼認為,那麼請拿出證據!但靜下來分析一下不難發現,這不可能是其他程式的影響,其他程序不可能影響我們程序對訊號的處理方式。 system()函式之前沒出錯,是因為systeme()函式依賴了系統的一個特性,那就是核心初始化程序時對SIGCHLD訊號的處理方式為SIG_DFL,這是什麼什麼意思呢?即核心發現程序的子程序終止後給程序傳送一個SIGCHLD訊號,程序收到該訊號後採用SIG_DFL方式處理,那麼SIG_DFL又是什麼方式呢?SIG_DFL是一個巨集,定義了一個訊號處理函式指標,事實上該訊號處理函式什麼也沒做。這個特性正是system()函式需要的,system()函式首先fork()一個子程序執行command命令,執行完後system()函式會使用waitpid()函式對子程序進行收屍。 通過上面的分析,我們可以清醒的得知,system()執行前,SIGCHLD訊號的處理方式肯定變了,不再是SIG_DFL了,至於變成什麼暫時不知道,事實上,我們也不需要知道,我們只需要記得使用system()函式前把SIGCHLD訊號處理方式顯式修改為SIG_DFL方式,同時記錄原來的處理方式,使用完system()後再設為原來的處理方式。
這樣我們可以遮蔽因系統升級或訊號處理方式改變帶來的影響。 驗證猜想 我們公司採用的是持續整合+敏捷開發模式,每天都會由專門的team負責自動化case的測試,每次稱為一個build,我們分析了本次build與上次build使用的系統版本,發現版本確實升級了。於是我們找到了相關team進行驗證,我們把問題詳細的描述了一下,很快對方給了反饋,下面是郵件回覆原文: LIBGEN 裡新增加了SIGCHLD的處理。將其ignore。為了避免殭屍程序的產生。 看來我們的猜想沒錯!問題分析到這裡,解決方法也清晰了,於是我們修改了我們的pox_system()函式:
typedef void (*sighandler_t)(int);
int pox_system(const char *cmd_line)
{
int ret = 0;
sighandler_t old_handler;
old_handler = signal(SIGCHLD, SIG_DFL);
ret = system(cmd_line);
signal(SIGCHLD, old_handler);
return ret;
}
我想這是呼叫system()比較完美的解決方案了,同時使用pox_system()函式封裝帶來了非常棒的易維護性,我們只需要修改此處一個函式,其他呼叫處都不需要改。 後來,查看了對方修改的程式碼,果然從程式碼上找到了答案:
if (signal(SIGCHLD, SIG_IGN) == SIG_ERR)
{
return -1;
}
else {
return 0;
} 其他思考 我們公司的程式碼使用SVN程序管理的,到目前為止有很多branch,逐漸的,幾乎每個branch都出現了上面的問題,於是我逐個在各個branchc上fix這個問題,幾乎忙了一天,因為有的branch已被鎖定,再想merge程式碼必須找相關負責人說明問題的嚴重性,還要在不同的環境上測試,我邊做這些邊想,系統這樣升級合適嗎? 首先,由於系統的升級導致我們的程式碼在測試時發現問題,這時再急忙去fix,造成了我們的被動,我想這是他們的一個失誤。你做的升級必須要考慮到對其他team的影響吧?何況你做的是系統升級。升級前需要做個風險評估,對可能造成的影響通知大家,這樣才職業嘛。 再者,據他們的說法,修改訊號處理方式是為了避免殭屍程序,當然初衷是好的,但這樣的升級影響了一些函式的使用方式,比如system()函式、wait()函式、waipid()、fork()函式,這些函式都與子程序有關,如果你希望使用wait()或waitpid()對子程序收屍,那麼你必須使用上面介紹的方式:在呼叫前(事實上是fork()前)將SIGCHLD訊號置為SIG_DFL處理方式,呼叫後(事實上wait()/waitpid()後)再將訊號處理方式設定為從前的值。你的系統升級,強制大家完善程式碼,確實提高了程式碼質量,但是對於這種升級我不是很認同,試想一下,你見過多少fork()->waitpid()前後都設定SIGCHLD訊號的程式碼?
使用system()函式的建議 上在給出了呼叫system()函式的比較安全的用法,但使用system()函式還是容易出錯,錯在哪?
那就是system()函式的返回值,關於其返回值的介紹請見上篇文章。system()函式有時很方便,但不可濫用!
1、建議system()函式只用來執行shell命令,因為一般來講,system()返回值不是0就說明出錯了;
2、建議監控一下system()函式的執行完畢後的errno值,爭取出錯時給出更多有用資訊;
3、建議考慮一下system()函式的替代函式popen();其用法在我的另一篇文章有介紹。

[email protected] 轉載請註明出處。

繼續轉該牛X博主的部落格,對於上文提到的system()函式的替換函式popen()的詳細介紹…萬分感謝博主:
【IPC通訊】基於管道的popen和pclose函式
標準I/O函式庫提供了popen函式,它啟動另外一個程序去執行一個shell命令列。 這裡我們稱呼叫popen的程序為父程序,由popen啟動的程序稱為子程序。 popen函式還建立一個管道用於父子程序間通訊。父程序要麼從管道讀資訊,要麼向管道寫資訊,至於是讀還是寫取決於父程序呼叫popen時傳遞的引數。下在給出popen、pclose的定義:

include

FILE * popen( const char * command,const char * type);
int pclose(FILE * stream);
下面通過例子看下popen的使用: 假如我們想取得當前目錄下的檔案個數,在shell下我們可以使用:
ls | wc -l 我們可以在程式中這樣寫:
#include

include #include #include

#define MAXLINE 1024
int main()
{
char result_buf[MAXLINE], command[MAXLINE];
int rc = 0; // 用於接收命令返回值
FILE *fp;
snprintf(command, sizeof(command), “ls ./ | wc -l”);
fp = popen(command, “r”);
if(NULL == fp)
{
perror(“popen執行失敗!”);
exit(1);
}
while(fgets(result_buf, sizeof(result_buf), fp) != NULL)
{
if(‘\n’ == result_buf[strlen(result_buf)-1])
{
result_buf[strlen(result_buf)-1] = ‘\0’;
}
printf(“命令【%s】 輸出【%s】\r\n”, command, result_buf);
}
rc = pclose(fp);
if(-1 == rc)
{
perror(“關閉檔案指標失敗”);
exit(1);
}
else
{
printf(“命令【%s】子程序結束狀態【%d】命令返回值【%d】\r\n”, command, rc, WEXITSTATUS(rc));
}
return 0;
}
編譯並執行:
gccpopen.c ./a.out 命令【ls ./ | wc -l】
輸出【2】 命令【ls ./ | wc -l】子程序結束狀態【0】命令返回值【0】
上面popen只捕獲了command的標準輸出,如果command執行失敗,子程序會把錯誤資訊列印到標準錯誤輸出,父程序就無法獲取。比如,command命令為“ls nofile.txt” ,事實上我們根本沒有nofile.txt這個檔案,這時shell會輸出“ls: nofile.txt: No such file or directory”。這個輸出是在標準錯誤輸出上的。通過上面的程式並無法獲取。 注:如果你把上面程式中的command設成“ls nofile.txt”,編譯執行程式你會看到如下結果:
gccpopen.c ./a.out ls: nofile.txt: No such file or directory
命令【ls nofile.txt】子程序結束狀態【256】命令返回值【1】 需要注意的是第一行輸出並不是父程序的輸出,而是子程序的標準錯誤輸出。 有時子程序的錯誤資訊是很有用的,那麼父程序怎麼才能獲取子程序的錯誤資訊呢? 這裡我們可以重定向子程序的錯誤輸出,讓錯誤輸出重定向到標準輸出(2>&1),這樣父程序就可以捕獲子程序的錯誤資訊了。
例如command為“ls nofile.txt 2>&1”,輸出如下:
命令【ls nofile.txt 2>&1】 輸出【ls: nofile.txt: No such file or directory】
命令【ls nofile.txt 2>&1】子程序結束狀態【256】命令返回值【1】
附:子程序的終止狀態判斷涉及到的巨集,設程序終止狀態為status. WIFEXITED(status)如果子程序正常結束則為非0值。 WEXITSTATUS(status)取得子程序exit()返回的結束程式碼,一般會先用WIFEXITED 來判斷是否正常結束才能使用此巨集。 WIFSIGNALED(status)如果子程序是因為訊號而結束則此巨集值為真。 WTERMSIG(status)取得子程序因訊號而中止的訊號程式碼,一般會先用WIFSIGNALED 來判斷後才使用此巨集。 WIFSTOPPED(status)如果子程序處於暫停執行情況則此巨集值為真。一般只有使用WUNTRACED 時才會有此情況。 WSTOPSIG(status)取得引發子程序暫停的訊號程式碼,一般會先用WIFSTOPPED 來判斷後才使用此巨集。 2011-11-12 任洪彩
[email protected] 轉載請註明出處。

但是根據上面那位博主說的使用system()函式前把SIGCHLD訊號處理方式顯式修改為SIG_DFL方式,同時記錄原來的處理方式,使用完system()後再設為原來的處理方式後,程式還是會死掉.而且看不到system的返回值是多少(因為system在執行系統命令的時候,程式已經掛掉了),故暫時使用博主提到的第二種解決方式使用popen()函式替代system()函式.修改後的函式如下
int my_system(const char * cmd)
{
FILE * fp;
int res; char buf[1024];
if (cmd == NULL)
{
printf(“my_system cmd is NULL!\n”);
return -1;
}
if ((fp = popen(cmd, “r”) ) == NULL)
{
perror(“popen”);
printf(“popen error: %s/n”, strerror(errno)); return -1;
}
else
{
while(fgets(buf, sizeof(buf), fp))
{
printf(“%s”, buf);
}
if ( (res = pclose(fp)) == -1)
{
printf(“close popen file pointer fp error!\n”); return res;
}
else if (res == 0)
{
return res;
}
else
{
printf(“popen res is :%d\n”, res); return res;
}
}
}
此時呼叫my_system()來執行system函式的功能(my_system函式中是使用popen()函式來實現的), 測試了一天,沒有再次出現程式突然死掉的問題(修改前連續迴圈呼叫system()函式測試,每10次就會至少導致程式掛掉一次.連續不停頓的呼叫). 以上是我對這個問題的總結,先做個記錄,待修復bug後再回來仔細研究.

相關推薦

對於linuxsystem()函式深度理解(轉載)

轉載自 http://blog.sina.com.cn/s/blog_8043547601017qk0.html 這幾天調程式(嵌入式linux),發現程式有時就莫名其妙的死掉,每次都定位在程式中不同的system()函式,直接在shell下輸入syste

對於linuxsystem 函式深度理解 整理

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

對於linuxsystem()函式深度理解(整理)

對於linux下system()函式的深度理解(整理)   (2013-02-07 08:58:54) 轉載▼ 標籤:  system()   popen()   sys

對於linuxsystem()函式深度理解

這幾天調程式(嵌入式linux),發現程式有時就莫名其妙的死掉,每次都定位在程式中不同的system()函式,直接在shell下輸入system()函式中呼叫的命令也都一切正常.就沒理這個bug,以為是其他的程式碼影響到這個,或是核心驅動檔案系統什麼的異常導致,昨天有出現了

linuxsystem函式詳解

一、system函式的簡單介紹 標頭檔案 #include <stdlib.h> 函式定義 int system(const char * string); 函式說明 system()會呼叫fork()產生子程序,由子程序來呼叫/bin/sh-

linuxsystem函式錯誤返回-1 錯誤原因NO child processes

呼叫system函式執行一個shell命令,返回-1,錯誤提示no child processes 但system可以執行成功 原因是呼叫system之前有放置忽略SIGCHLD的語句 signal(SIGCHLD, SIG_IGN); 如果SIGCHLD訊號行為被

c語言實現linux高危函式system (簡易V1.0版本)

system這個函式真的是要慎用,一不小心就會留下漏洞。 下面是用c語言簡易的實現了一下system函式 #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<err

c語言實現linux高危函式system (簡易V1.0版本)

system這個函式真的是要慎用,一不小心就會留下漏洞。 下面是用c語言簡易的實現了一下system函式 #include<stdio.h> #include<stdlib.h> #include<unistd.h> #inc

轉載Linuxgetopt()函式的使用

步入正題: 我們的主角----getopt()函式。 英雄不問出處,getopt()函式的出處就是unistd.h標頭檔案(哈哈),寫程式碼的時候千萬不要忘記把他老人家include上。 再來看一下這傢伙的原型(不是六耳獼猴): int getopt(int

Linuxsystem與popen函式

曾經的曾經,被system()函式折磨過,之所以這樣,是因為對system()函數了解不夠深入。只是簡單的知道用這個函式執行一個系統命令,這遠遠不夠,它的返回值、它所執行命令的返回值以及命令執行失敗原因如何定位,這才是重點。當初因為這個函式風險較多,故拋棄不用,改

關於linuxsystem()函數的總結

min ons 了解 shell 等我 exe urn per pro 先來看一下system()函數的簡單介紹: #include int system(const char *command) system()函數調用/bin/sh來執行參數指定的命令,/bin/sh

Linuxgetopt()函式的使用

Linux下getopt()函式的簡單使用 步入正題: 我們的主角----getopt()函式。 英雄不問出處,getopt()函式的出處就是unistd.h標頭檔案(哈哈),寫程式碼的時候千萬不要忘記把他老人家include上。   再來看一下這傢伙的原型(不是六耳獼

Linuxtime函式

Linux下time函式都在time.h標頭檔案中。 1、標頭檔案 和時間有關的標頭檔案有以下幾個: time.h sys/time.h sys/times.h sys/timeb.h sys/timex.h time.h是C標準庫的標頭檔案,其餘sys開頭的都是Linux系統自己的標頭檔

對於Linux的伺服器程式設計(2)

對於驚群問題,我們可以使用一個主執行緒來接受連線,並且把這個連線套接字傳遞到子程序裡面,讓子程序來處理這個連線。這種方法需要程序間通訊:通過Unix套接字來在程序之間傳遞套接字。【注意不能使用Unix套接字***直接***傳遞描述符到子程序,因為雖然父程序和子程序獲得的檔案描述符相同,但是子程序

對於Linux的伺服器程式設計(1)

在Linux下面,對於海量連線並且每個連線在大部分時間裡面都是不活躍的情況下,我們使用Epoll來解決C10K[C10M]問題。 1.如何使用Epoll:man Epoll。即為三個系統呼叫。 2.在伺服器擁有多個CPU的情況下,我們需要多執行緒或者多程序來幫助我們提高程式的效能,所以就需要

Linuxgets函式警告

由於Linux下的gcc編譯器不支援gets函式,程式編譯過後會出現一個警告,即:“warning: the `gets' function is dangerous and should not be used.”   此時,可以用fgets函式代替,函式在標頭檔案stdio.h中,

Linux系統函式

Linux下系統函式 rand()函式 獲取02147483647(0RAND_MAX)之間的隨機數。真隨機需要srand()設定種子。一般用時間作為srand()的引數 #include<unistd.h> int rand(void) void srand(uns

linux封裝函式庫——動態庫.so和靜態庫.a(程式碼實現及連結方式)

在linux環境下的連結庫分為靜態連結庫(.a庫)和動態連結庫(.so庫),其作用是把C程式編譯好做成一種可執行連結檔案,主程式檔案呼叫這些程式的函式介面是可以使用a庫或so庫,在主程式中只需要include含有庫中提供的函式介面宣告的標頭檔案即可。所以學會如何

Linuxselect函式檔案描述符0狀態的問題

當然是在有輸入或者輸出時檔案描述符的讀寫狀態改變咯,比如標準輸入的檔案描述符是0,如果用select來等待0號檔案描述符,那麼當在鍵盤上敲字元時開始,就是檔案描述符的讀寫狀態改變之時,這時select函式就會返回;對於套接字描述符來說也是這樣,用select來等待一個伺服器描

linux時間函式

void get_local_time(long sec, char *plocaltime, int len) { struct tm t1 = {0}; localtime_r(&sec, &t1); snprintf(plocaltime, len, "%04d-%02