日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

linux系統(tǒng)下,c 程序,調(diào)用system命令失敗,分析過(guò)程

 angelbrian 2013-02-01

首先,該程序運(yùn)行,需要很大的數(shù)據(jù),需要很大內(nèi)存。在測(cè)試小數(shù)據(jù)的時(shí)候,程序沒(méi)有任何問(wèn)題,在運(yùn)行測(cè)試大數(shù)據(jù)的時(shí)候,出現(xiàn)問(wèn)題。個(gè)人認(rèn)為程序本身編程代碼應(yīng)該沒(méi)有問(wèn)題。

通過(guò)程序錯(cuò)誤定位,定位到了system命令。system命令調(diào)用,程序根本沒(méi)有反應(yīng)。完全將system命令忽略。

 

=========================

 

每個(gè)命令都有返回值,重新試過(guò),發(fā)現(xiàn)調(diào)用system命令的返回值都是-1.

  cerr<<"before pdflatex"<<endl;
    sprintf( cmd, "%s %s", "pdflatex -output-directory=/home/user/evaluation", outfilename );
   cerr<<"pdflatex : "<<outfilename<<endl;
    system_cmd = system( cmd );
    cerr<<"system_cmd : "<<system_cmd<<endl;
    system_cmd = system( cmd );
    cerr<<"system_cmd : "<<system_cmd<<endl;

 

=========================

 

研究system命令。為何返回-1?

system()會(huì)調(diào)用fork()產(chǎn)生子進(jìn)程,由子進(jìn)程來(lái)調(diào)用/bin/sh-c string來(lái)執(zhí)行參數(shù)string字符串所代表的命令,此命>令執(zhí)行完后隨即返回原調(diào)用的進(jìn)程。在調(diào)用system()期間SIGCHLD 信號(hào)會(huì)被暫時(shí)擱置,SIGINT和SIGQUIT 信號(hào)則會(huì)被忽略。

返回值:

如果fork()失敗 返回-1:出現(xiàn)錯(cuò)誤

如果exec()失敗,表示不能執(zhí)行Shell,返回值相當(dāng)于Shell執(zhí)行了exit(127)

如果執(zhí)行成功則返回子Shell的終止?fàn)顟B(tài)

如果system()在調(diào)用/bin/sh時(shí)失敗則返回127,其他失敗原因返回-1。若參數(shù)string為空指針(NULL),則返回非零值>。如果system()調(diào)用成功則最后會(huì)返回執(zhí)行shell命令后的返回值,但是此返回值也有可能為 system()調(diào)用/bin/sh失敗所返回的127,因此最好能再檢查errno 來(lái)確認(rèn)執(zhí)行成功。

 

=====================================

 

那么,將錯(cuò)誤定位為fork()失敗。

下面是fork():

fork調(diào)用的一個(gè)奇妙之處就是它僅僅被調(diào)用一次,卻能夠返回兩次,它可能有三種不同的返回值:

在父進(jìn)程中,fork返回新創(chuàng)建子進(jìn)程的進(jìn)程ID;

在子進(jìn)程中,fork返回0;

如果出現(xiàn)錯(cuò)誤,fork返回一個(gè)負(fù)值;

fork出錯(cuò)可能有兩種原因:

(1)當(dāng)前的進(jìn)程數(shù)已經(jīng)達(dá)到了系統(tǒng)規(guī)定的上限,這時(shí)errno的值被設(shè)置為EAGAIN。

(2)系統(tǒng)內(nèi)存不足,這時(shí)errno的值被設(shè)置為ENOMEM。(關(guān)于errno的意義,請(qǐng)參考本系列的第一篇文章。)

fork系統(tǒng)調(diào)用出錯(cuò)的可能性很小,而且如果出錯(cuò),一般都為第一種錯(cuò)誤。如果出現(xiàn)第二種錯(cuò)誤,說(shuō)明系統(tǒng)已經(jīng)沒(méi)有可分配的內(nèi)存,正處于崩潰的邊緣,這種情況對(duì)Linux來(lái)說(shuō)是很罕見的。

 

============================

 

下面想到的就是查看errno的內(nèi)容。

當(dāng)linux中的C api函數(shù)發(fā)生異常時(shí),一般會(huì)將errno變量(需include errno.h)賦一個(gè)整數(shù)值,不同的值表示不同的含義,可以通過(guò)查看該值推測(cè)出錯(cuò)的原因,在實(shí)際編程中用這一招解決了不少原本看來(lái)莫名其妙的問(wèn)題。但是 errno是一個(gè)數(shù)字,代表的具體含義還要到errno.h中去閱讀宏定義,而每次查閱是一件很繁瑣的事情。有下面幾種方法可以方便的得到錯(cuò)誤信息
 (1)void perror(const char *s)
函數(shù)說(shuō)明
perror ( )用來(lái)將上一個(gè)函數(shù)發(fā)生錯(cuò)誤的原因輸出到標(biāo)準(zhǔn)錯(cuò)誤(stderr),參數(shù)s 所指的字符串會(huì)先打印出,后面再加上錯(cuò)誤原因字符串。此錯(cuò)誤原因依照全局變量 errno 的值來(lái)決定要輸出的字符串。
 (2) char *strerror(int errno)
將錯(cuò)誤代碼轉(zhuǎn)換為字符串錯(cuò)誤信息,可以將該字符串和其它的信息組合輸出到用戶界面例如
fprintf(stderr,"error in CreateProcess %s, Process ID %d ",strerror(errno),processID)
注:假設(shè)processID是一個(gè)已經(jīng)獲取了的整形ID
 (3)printf("%m", errno);
另外不是所有的地方發(fā)生錯(cuò)誤的時(shí)候都可以通過(guò)error獲取錯(cuò)誤代碼,例如下面的代碼段

#include"stdio.h"
#include "stdlib.h"
#include "errno.h"
#include "netdb.h"
#include "sys/types.h"
#include "netinet/in.h"
int main (int argc, char *argv[])
{
struct hostent *h;
if (argc != 2)
{
fprintf (stderr ,"usage: getip address\n");
exit(1);
}

if((h=gethostbyname(argv[1])) == NULL)
{

herror(“gethostbyname”);
exit(1);
}

printf(“Host name : %s\n”, h->h_name);
printf(“IP Address : %s\n”, inet_ntoa (*((struct in_addr *)h->h_addr)));
return 0;
}


 通過(guò)上面的代碼可以看到:使用gethostbyname()函數(shù),你不能使用perror()來(lái)輸出錯(cuò)誤信息(因?yàn)殄e(cuò)誤代碼存儲(chǔ)在 h_errno 中而不是errno 中。所以,你需要調(diào)用herror()函數(shù)。
你 簡(jiǎn)單的傳給gethostbyname() 一個(gè)機(jī)器名(“bbs.tsinghua.edu.cn”),然后就從返回的結(jié)構(gòu)struct hostent 中得到了IP 等其他信息.程序中輸出IP 地址的程序需要解釋一下:h->h_addr 是一個(gè)char*,但是inet_ntoa()函數(shù)需要傳遞的是一個(gè)struct in_addr 結(jié)構(gòu)。所以上面將h->h_addr 強(qiáng)制轉(zhuǎn)換為struct in_addr*,然后通過(guò)它得到了所有數(shù)據(jù)。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多