在linux中我们可以很方便的使用system启动子程序,但是system有个不足就是它对子程序的掌控很弱,连返回数值都很难获取。
下面是一段使用execvp来调用子程序的示例代码,关于下面的代码有几点特殊说明:
1) folk(): 会从主程序中复制出一个新的程序,如果folk返回0就是子程序,否则那就是还是当前的程序。
2) wait() : 在主程序中你可以自己决定要等待子程序返回才继续运算这样保持同步还是异步的不等子程序的结果就继续往下运行。
3) WEXITSTATUS: 用来获取子程序的返回值
4) freopen: 默认情况下子程序的log会和主程序的一起都在终端中打印出来,这可能不是我们想要的,所以要把子程序的log重新导入到其他的log
5) execvp: 这个函数如果正常运行是不会有返回的,有返回说明启动的程序出现异常。对于没有返回的函数理解起来比较费劲,因为通常我们讲函数都会有返回的,但如果想到这个是一个独立的进程,那就可以理解了。
#include
#include
int callApp (char* program, char** arg_list, bool isWaiting) {
pid_t child_pid;
/* Duplicate this process. */
child_pid = fork ();
//return child_pid;
if (child_pid != 0){
/* This is the parent process. */
if(isWaiting == true){
/* Wait for the child process to complete. */
int child_status;
wait (&child_status);
int retCode = WIFEXITED (child_status);
// cout << "Finish " << program << " " << retCode << " " << WEXITSTATUS (child_status) << endl;
if (retCode){
// printf ("the child process exited normally, with exit code %d\n", WEXITSTATUS (child_status));
return WEXITSTATUS(child_status);
} else{
// printf ("the child process exited abnormally\n");
return -1;
}
}
}else {
/* Now execute PROGRAM, searching for it in the path. */
string fLog = _temp_path+"/subprocess_log.log";
freopen(fLog.c_str(), "w", stdout);
string fErrorLog = _temp_path+"/subprocess.log";
freopen(fErrorLog.c_str(), "w", stderr);
chdir(_temp_path.c_str());
int ret = execvp (program, arg_list);
fclose(stdout);
/* The execvp function returns only if an error occurs. */
cout << "execvp failed with error code " << ret << endl;
abort();
return -1;
}
}
// call sample
char subProcessBin[1024] = "myBin";
char* configFile = "myConfig";
char* arg_list[]= {
subProcessBin,
"-c",
configFile,
NULL
};
int retCode = callApp(subProcessBin, arg_list, true);