C 等待(NULL)函数不工作,并且父进程总是在子进程之前运行
我对以下代码有问题。 它类似于在Unix平台上使用C进行手动shell程序实现。如果用户输入命令,它应该执行并返回相应的结果。 如果用户在末尾输入“C 等待(NULL)函数不工作,并且父进程总是在子进程之前运行,c,linux,unix,process,C,Linux,Unix,Process,我对以下代码有问题。 它类似于在Unix平台上使用C进行手动shell程序实现。如果用户输入命令,它应该执行并返回相应的结果。 如果用户在末尾输入“&”,则父进程无需等待子进程完成 #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <signal.h> #include <stdlib.h> #include <string.h>
&
”,则父进程无需等待子进程完成
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#define HISTORY_LIMIT 20
#define BUFFER_LIMIT 100
#define MAX_WORDS 50
int count = 0;
char history[HISTORY_LIMIT][BUFFER_LIMIT];
int tokenize(char *str, char **args, int *bRun)
{
int i, argc = 0;
char *token;
if (count == HISTORY_LIMIT)
{
// alignHistory();
}
// strcpy(history[count],str);
count++;
token = strtok(str, " \t\n");
for (i = 0; token != NULL; i++)
{
args[i] = token;
token = strtok(NULL, " \t\n");
argc++;
}
for (i = 0; i < argc; i++)
{
if (strcmp(args[i], "&") == 0)
{
*bRun = 1;
args[i] = NULL;
}
}
return argc;
} // end of tokenize function
void handleSignal(int sign)
{
if (sign == SIGINT)
{
// getHistory();
}
} // end of handlesignal
int main(void)
{
char *args[MAX_WORDS];
char buffer[BUFFER_LIMIT];
pid_t pid;
int argc;
int bgRun = 0;
if (signal(SIGINT, handleSignal) == SIG_ERR)
{
printf("can't handle ctrl-c");
return 0;
}
while (1)
{
bgRun = 0;
memset(args, 0, MAX_WORDS);
printf("osh>");
fgets(buffer, BUFFER_LIMIT, stdin);
argc = tokenize(buffer, args, &bgRun);
if (argc == 0)
continue;
if (strcmp(args[0], "exit") == 0)
break;
if (strcmp(args[0], "history") == 0)
getHistory();
// else if(strcmp(args[0],"hello")==0)printf("Hi There, How are you ?\n");
else
{
pid = fork();
if (pid == 0)
{
execvp(args[0], args);
return 0;
}
else
{
if (bgRun == 0)
wait(NULL);
}
}
}
}
但是所需的结果应该是这样的(if&用于命令)
所以我使用了bgRun
int变量,并在命令有1时赋值1
但这不起作用。我认为这是等待(NULL)
的问题。请从这个恶魔那里救我。您没有说要等待哪个子进程,所以第三个命令(不应该是后台命令)被认为在第二个命令退出时完成
哎呀
您需要处理
SIGCHLD
并在后台进程终止时获取后台进程,还需要检查退出的进程是否是当前正在运行的“前台”进程,而不是正在完成的后台作业waitpid()
允许您等待特定流程。您能澄清一下吗?实际产出和预期产出之间的实质性差异是什么?我可以看到明显的区别,但不清楚为什么一个是正确的输出,而另一个不是。请修改代码的格式-如果没有适当的缩进,很难阅读。我的意图是如果命令中添加了&则父进程不必等待子进程完成,但如果您观察预期与获得的o/p的最后四行..我已输入“whoami&”,并单击enter(因为它是“&”父进程不应该等待子进程,所以它首先被执行,“osh>”在“root”之前被打印),直到现在一切都很好。但问题出现在下一步,我输入了“whoami”,这里父进程应该等待子进程执行,因为我使用了wait(null),但不幸的是父进程没有等待,所以我得到了o/p“osh>”在rootAnd之前,OP可能需要注意它甚至不知道它有过的孩子(我对一个进程做了这件事——是故意的,不是偶然的)。你必须检查wait()
是否返回了你期望的PID,如果没有,决定怎么做。盲目地忽略返回值是不好的。通常,wait(NULL)
也很糟糕;您经常想知道孩子终止的原因/方式。对于调试来说,这是至关重要的;您需要捕获PID和状态并报告它们,以便知道发生了什么。@JonathanLeffler如果您能解释我在代码中必须做的更改,那就太好了。请在他的代码中提及任何需要更改的代码@Ben Voigt
osh>whoami
root
osh>whoami &
osh>root
whoami
osh>root
osh>whoami
root
osh>whoami &
osh>root
whoami
root
osh>