fork - 我可以退出 parent 吗?
fork - Can I exit from parent?
我编写了一个代码,它将调用 exec
,如下所示。但是如果我从 main
调用 isValid
,child 和 parent 进程都在 returning 并且我得到了两次输出。
我想退出 exec 并且只想检查一次 main 中的 return 值。我需要退出哪个进程才能正常工作?
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");
}
}
您可能应该做一些小事(也许某些 usleep(3) for a few milliseconds) after the fork
but before the waitpid
to have some real chance to get the waitpid(2) 调用成功。否则,其他进程可能不会被安排到 运行。
顺便说一句,您应该从 waitpid
测试 return 值 ,例如代码
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, read several chapters of Advanced Linux Programming, and consider using daemon(3)
另外,在execl
之后一定要加上
perror("execl");
exit(EXIT_FAILURE);
处理 罕见的 案例 execl
失败。
当execl
失败时可能出现双倍输出。上面的代码不检查 execl
return 值。实际上 execl
return 仅在出现故障时出现,因此无需检查 returned 值,但无论如何都需要处理错误。
编辑:
如果 exec
失败则:
- Child's
isValid()
returns 函数末尾的 0 和主要打印 "Invalid"
- Parent 等待 child 退出,然后 WIFEXITED 为真,因为 child 退出,WEXITSTATUS 为 0,因为 child 正常退出。 Parent 的
isValid
returns 1 和 "Valid" 被打印出来。
#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");
}
}
我编写了一个代码,它将调用 exec
,如下所示。但是如果我从 main
调用 isValid
,child 和 parent 进程都在 returning 并且我得到了两次输出。
我想退出 exec 并且只想检查一次 main 中的 return 值。我需要退出哪个进程才能正常工作?
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");
}
}
您可能应该做一些小事(也许某些 usleep(3) for a few milliseconds) after the fork
but before the waitpid
to have some real chance to get the waitpid(2) 调用成功。否则,其他进程可能不会被安排到 运行。
顺便说一句,您应该从 waitpid
测试 return 值 ,例如代码
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, read several chapters of Advanced Linux Programming, and consider using daemon(3)
另外,在execl
之后一定要加上
perror("execl");
exit(EXIT_FAILURE);
处理 罕见的 案例 execl
失败。
当execl
失败时可能出现双倍输出。上面的代码不检查 execl
return 值。实际上 execl
return 仅在出现故障时出现,因此无需检查 returned 值,但无论如何都需要处理错误。
编辑:
如果 exec
失败则:
- Child's
isValid()
returns 函数末尾的 0 和主要打印 "Invalid" - Parent 等待 child 退出,然后 WIFEXITED 为真,因为 child 退出,WEXITSTATUS 为 0,因为 child 正常退出。 Parent 的
isValid
returns 1 和 "Valid" 被打印出来。
#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");
}
}