我已经编写了一个代码,它将调用exec
,如下所示。但是,如果我从isValid
调用main
,则子进程和父进程都将返回,并且我将获得两次输出。
我想从exec中获取并且只想在main中检查返回值一次。我需要退出哪个进程以使其正常工作?
int isValid(void)
{
int number, statval;
int child_pid;
child_pid = fork();
if(child_pid == -1) { printf("Could not fork! \n"); exit( 1 ); }
else if(child_pid == 0)
{
execl(...); // Child
}
else
{
// Parent
waitpid( child_pid, &statval, WUNTRACED );
if(WIFEXITED(statval))
{
if (WEXITSTATUS(statval) == 0)
return 1;
else
return 0;
}
else
printf("Child did not terminate with exit\n");
}
return 0;
}
int main(void)
{
if (isValid())
{
printf("Valid\n");
}
else
{
printf("Invalid\n");
}
}
答案 0 :(得分:3)
execl
失败时可能会出现加倍输出。上面的代码不会检查execl
返回值。实际上execl
仅在失败的情况下返回,因此无需检查返回的值,但无论如何都必须处理错误。
修改强>
如果exec
失败,那么:
isValid()
在功能结束时返回0,主要打印"无效" isValid
返回1和"有效"印刷。答案 1 :(得分:1)
你可能应该在fork
之后但在waitpid
之前做一些微小的事情(可能只有usleep(3)几毫秒),以便有机会获得waitpid(2)调用成功。否则,可能会发生其他进程未安排运行的情况。
顺便说一句,你应该从waitpid
测试返回值,.e.g。代码
statval = 0;
pid_t wpid = waitpid(child_pid, &statval, WUNTRACED );
if (wpid>0) {
assert (wpid == child_pid);
if (WIFEXITED(statval)) {
if (WEXITSTATUS(statval) == 0)
return 1;
最后,关于问题的标题,请阅读job control wikipage,阅读Advanced Linux Programming的几个章节,并考虑使用daemon(3)
此外,在execl
确定要放
perror("execl");
exit(EXIT_FAILURE);
处理execl
失败的罕见案例。
答案 2 :(得分:1)
#include <sys/shm.h>
int *tabPID;
int isValid(void)
{
int number, statval;
if(fork() == 0){
tabPID[1] = getpid();
execl(...); // Child
return -1;
}
// Parent
tabPID[0]=getpid();
usleep(10);//as Basile Starynkevitch suggests
waitpid(tabPID[1], &statval, WUNTRACED );
if(WIFEXITED(statval))
{
if (WEXITSTATUS(statval) == 0)
return 1;
else
return 0;
}
else
printf("Child did not terminate with exit\n");
return 0;
}
int main(void)
{
shmId = shmget(1234, 2*sizeof(int), IPC_CREAT|0666);
tabPID = shmat(shmId, NULL, 0);
if (isValid())
{
printf("Valid\n");
}
else
{
printf("Invalid\n");
}
}