我正在努力正确地理解fork()
,pipe()
和execvp()
,并希望获得有关此代码在哪里出错以及应该从何而来的指南。据我了解,如果要运行多个进程,请使用fork()
语句for
n次,如下所示。要维护对父代与众多子代之间的每个通信“通道”的引用,请使用2D文件描述符(例如fd[n][2]
)。此外,要允许2种方式通信,您需要使用2个FD。调用exevp()
时,它将用execvp()
创建的过程替换被调用的过程。
因此,我创建了一个简单的程序,该程序分叉一个进程的2个副本,其唯一目的是立即返回父进程发送的字符串。从这一刻开始,它应该向子进程0,然后是子进程1发送一条消息。然后,它永恒地等待,直到完成某些操作以终止子进程或父进程为止。但是,我遇到2个问题。首先,此当前程序在父进程的第一个read
/ printf
语句处停止,我得到以下结果,提示我输入按Enter时不执行任何操作的值。我知道发生此错误是由于我的execvp
程序造成的,因为删除了fgets
并只是printf
输入了一个值并退出了预期的工作。但是,我需要在那里fgets
,因为我希望能够返回到该过程并稍后发送更多消息。
Child 0
| <--- Prompts me to enter value
预期:
Child 0
Process 0 received: test message
Child 1
Process 1 received: test message
这是我的主程序:
int main () {
char buff[50];
int pipe_parent[2][2];
int pipe_child[2][2];
int pids[2];
for (int i = 0; i < 2; i++) {
char id[snprintf(NULL, 0, "%d", i) + 1];
sprintf(id, "%d", i);
char* prog[] = {"./test", id, NULL};
if (pipe(pipe_parent[i]) == -1 || pipe(pipe_child[i]) == -1) {
exit(1);
}
int pid = fork();
if (pid > 0) {
pids[i] = pid;
close(pipe_child[i][0]);
close(pipe_parent[i][1]);
int in = pipe_child[i][1];
int out = pipe_parent[i][0];
write(out, "test message\n", 13); //hard coded but should use strlen + 1
read(in, buff, 50);
//The code below does not work and so probably the read above too
printf("Child: %s", buff); //Does not print anything and starts waiting for use input here.
//Inputting anything here does nothing
} else if (pid == 0) {
print("Child %d", i);
close(pipe_child[i][1]);
close(pipe_parent[i][0]);
dup2(pipe_child[i][0], STDIN_FILENO);
dup2(pipe_parent[i][1], STDOUT_FILENO);
close(pipe_child[i][0]);
close(pipe_child[i][1]);
execvp(prog[0], prog);
exit(1); //Should not reach here unless error
} //Should add error check here with else
for (int i = 0; i < 2; i++) {
int status;
waitpid(pids[i], &status, 0);
}
return 0;
}
和我的另一个获得execvp
的程序:
int main(int argc, char** argv) {
char buff[50];
while(fgets(buff, sizeof(buff), stdin) != NULL) {
printf("Process &d received: %s", atoi(argv[1]), buff);
}
printf("Process %d closed", atoi(argv[1]));
return 0;
}
我的第二个问题是,假设以上程序正常工作,我不知道如何选择与特定过程进行通信。我希望程序以某种方式发送消息,以向进程0,然后1,然后0,...等发送消息(依我指定的其他顺序),直到完成阻止它的操作为止。我认为对于简单的0,1,0,1 ...代码,代码看起来像这样:
int counter = 0;
while(counter < 5) {
for (int i = 0; i < 2; i++) {
//setup out and in to be pipe_child/parent[i][0/1]
write(out, "message", len);
//read();
//printf();
}
counter++;
}
如果我可以在哪里找到可以工作的提示,将不胜感激。
编辑:execl()
至execvp()