你需要了解fork和execv如何协同工作
- fork()克隆当前进程,返回0给子进程,返回childpid给父进程
- fork()有可能失败,返回-1表示失败,需要判断
- execv()用新进程替换复制的父进程
- 典型的fork/exec组合将子进程替换为新进程
- 通常情况下,你会fork多个子进程,并希望它们同时运行
- 然而,你要求它们按顺序运行,也就是一个接一个地运行
- 因此,在启动第二个进程之前,你需要等待第一个进程完成
- 所以你需要使用某种wait()的变体,下面的示例使用waitpid()等待特定的子进程
你需要stdlib来进行退出处理(以防execv失败),以及errno来输出原因
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
您可能希望查看您的子进程退出的原因(核心转储、信号、正常退出),因此我添加了这个函数。
#include <sys/types.h>
#include <sys/wait.h>
int
exitreason(pid_t cid, int status)
{
if( WIFEXITED(status) )
{
printf("child %d terminated normally, that is, by calling exit(3) or _exit(2), or by returning from main().\n",cid);
if( WEXITSTATUS(status) )
{
printf("child %d exit status %d. This consists of the least significant 8 bits of the status argument that the child specified in a call to exit(3) or _exit(2) or as the argument for a return statement in main().\n",cid,WEXITSTATUS(status));
}
}
if( WIFSIGNALED(status) )
{
printf("child %d process was terminated by a signal.\n",cid);
if( WTERMSIG(status) )
{
printf("child %d signal %d that caused the child process to terminate.\n",cid,WTERMSIG(status));
}
if( WCOREDUMP(status) )
{
printf("child %d produced a core dump. WCOREDUMP() is not specified in POSIX.1-2001 and is not available on some UNIX implementations (e.g., AIX, SunOS). Only use this enclosed in #ifdef WCOREDUMP ... #endif.\n",cid);
}
}
if( WIFSTOPPED(status) )
{
printf("child %d process was stopped by delivery of a signal; this is only possible if the call was done using WUNTRACED or when the child is being traced (see ptrace(2)).\n",cid);
if( WSTOPSIG(status) )
{
printf("child %d number of the signal which caused the child to stop.\n",cid);
}
}
if( WIFCONTINUED(status) )
{
printf("child %d process was resumed by delivery of SIGCONT.\n");
}
}
这里是您的程序,标注有注释,解释了哪些代码是由父进程处理,哪些是由子进程处理。
int main (int argc, char *argv[])
{
char proc1[] = "/bin/echo";
char proc2[] = "/bin/echo";
pid_t cid1, cid2, cidX;
int status=0;
int waitoptions = 0;
int res;
if( (cid1 = fork()) == 0 )
{
printf("in child1\n");
if( (res = execv(proc1, &argv[1])) < 0 )
{
printf("error: child1: %d exec failed %d\n", cid1, errno);
printf("error: cannot execv %s\n",proc1);
exit(91);
}
}
else if( cid1 > 0 )
{
cidX = waitpid(cid1, &status, waitoptions);
printf("child1: %d res %d\n", cid1, res);
exitreason(cid1, status);
}
else
{
printf("error: child1 fork failed\n");
}
if( (cid2 = fork()) == 0 )
{
printf("in child2\n");
if( (res = execv(proc2, &argv[1])) < 0 )
{
printf("error: child2: %d exec failed %d\n", cid2, errno);
printf("error: cannot execv %s\n",proc2);
exit(92);
}
}
else if( cid2 > 0 )
{
cidX = waitpid(cid2, &status, waitoptions);
printf("child2: %d res %d\n", cid2, res);
exitreason(cid2, status);
}
else
{
printf("error: child2 fork failed\n");
}
}