【发布时间】:2020-06-27 05:53:48
【问题描述】:
我是一名学习 C 以及如何使用 fork() 创建进程的学生 你能解释一下这两个代码有什么区别吗,因为我都试过了,但它们都没有按预期工作。
child = fork();
child1 = fork();
if (child == 0 && child1 == 0){//Parent}
else if (child > 0 && child1 == 0){//first child}
else if (child == 0 && child1 > 0){//second child}
else {third child}
这是创建孩子的正确方法还是下面的方法?
child = fork();
if (child == 0)
{
child1 = fork();
if (child1 == 0)
{// grandchild
}
else
{//child
}
}
else
{//parent
}
这些是我写的让我感到困惑的例子。 这是我遇到问题的代码
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char ** argv)
{
pid_t child;
pid_t child1;
// at least, there should be 3 arguments
// 2 for the first command, and the rest for the second command
//printf("%d\n", argc);
if (argc < 4) {
fprintf(stderr, "Usage: %s cmd1 cmd1_arg cmd2 [cmd2_args ..]\n", argv[0]);
return 1;
}
child = fork();
//pid_t child1;
// TODO
if (child < 0)
{
perror("fork()");
exit(EXIT_FAILURE);
}
if (child == 0)//child1
{
//printf("exited=%d exitstatus=%d\n", WIFEXITED(exitStatus), WEXITSTATUS(exitStatus));
child1 = fork();
if (child1 == 0)//grandchild
{
execlp(argv[1],argv[1],argv[2],NULL);
perror("execlp()");
exit(EXIT_FAILURE);
}
else //first child
{
int status1;
waitpid(child1, &status1, 0);
printf("exited=%d exitstatus=%d\n", WIFEXITED(status1), WEXITSTATUS(status1));
execvp(argv[3], (argv + 3));
perror("execlp()");
exit(EXIT_FAILURE);
}
}
else//parent
{
int status;
waitpid(child, &status, 0);
printf("exited=%d exitstatus=%d\n", WIFEXITED(status), WEXITSTATUS(status));
}
return 0;
}
我能够让代码按预期工作,但我对如何使用 WIFEXITED 和 WEXITSTATUS 感到困惑。 我运行此代码时的代码输出是
execlp(): No such file or directory
Makefile
exited=1 exitstatus=0
正确的输出是:
execlp(): No such file or directory
Makefile
exited=1 exitstatus=1
exited=1 exitstatus=0
本测试用例中使用的参数
cal -3 ls Makefile
为什么我错过了第二个出口打印?
【问题讨论】:
-
你有评论
if (child == 0 && child1 == 0){//Parent}——这是错误的;父级的 PID 值均非零。 PID 值都为零的进程是孙进程。 -
@JonathanLeffler 对不起,这是一个错字,我明白你在说什么,但我不确定解决我手头问题的最佳方法是什么。我想运行两个 exe 命令并打印退出状态。你能告诉我我做错了什么吗?
-
您的示例命令行令人费解。你说
cal -3 ls Makefile,你的使用信息说Usage: %s cmd1 cmd1_arg cmd2 [cmd2_args ..]。假设你的程序叫做cal(请注意,至少在许多系统上,有一个标准程序叫做cal——试试cal 9 1752),那么你的cmd1是-3,它的参数是@ 987654335@,而cmd2就是Makefile,不是很常规。我希望像./cal ls -l cat Makefile这样的调用。假设您希望cmd1 cmd1arg在运行cmd2 [cmd2arg ...]之前运行并完成,我们是否正确?
标签: c fork child-process execvp waitpid