【发布时间】:2015-01-18 18:58:30
【问题描述】:
我正在尝试编写一个使用管道在父级和两个子级之间发送信息的 C 程序。该程序的目标是为字符串实现类似于归并排序的功能。我读了字符串的数量,然后是字符串。字符串在 2 个孩子之间递归分配,直到每个孩子只有一个字符串。我必须重定向孩子的标准输入以从父母的标准输出中读取。
由于某种原因,没有一个孩子比第一个字符串读得更多。 我该如何解决这个问题?
int main(int argc, char * argv[]) {
int nrrows = 0;
char * buffer = NULL;
size_t n = 0;
getline(&buffer, &n, stdin);
char * endptr;
nrrows = strtol(buffer, &endptr, 10);
char rows[nrrows][MAX_LEN];
int i = 0;
n = 0;
while(i < nrrows) {
char * row = NULL;
getline(&row, &n, stdin);
strcpy(rows[i], row);
i++;
}
if(nrrows == 1) {
fprintf(stderr, "%s", rows[0]);
return 0;
}
int fdcp1[2];
int fdcp2[2];
if(pipe(fdcp1) < 0) {
fprintf(stderr, "pipe unsuccessfull\n");
return EXIT_FAILURE;
}
if(pipe(fdcp2) < 0) {
fprintf(stderr, "pipe unsuccessfull\n");
return EXIT_FAILURE;
}
pid_t chpid1 = fork();
if(chpid1 < 0) {
fprintf(stderr, "fork unsuccessfull\n");
return EXIT_FAILURE;
}
else if(chpid1 == 0) {
close(fdcp2[0]);
close(fdcp2[1]);
close(fdcp1[1]);
dup2(fdcp1[0], STDIN_FILENO);
execlp("./forksort", "child1", NULL);
}else {
close(fdcp1[0]);
dup2(fdcp1[1], STDOUT_FILENO);
double half = (nrrows / 2);
int h = half;
char b[2];
b[0] = '0' + h;
b[1] = '\n';
write(fdcp1[1], b, sizeof(b));
for(i = 0; i < h; i ++) {
rows[i][strlen(rows[i])] = '\0';
write(fdcp1[1], rows[i], sizeof(rows[i]));
}
pid_t chpid2 = fork();
if(chpid2 < 0) {
fprintf(stderr, "fork unsuccessfull\n");
return EXIT_FAILURE;
}else if(chpid2 == 0) {
close(fdcp1[0]);
close(fdcp1[1]);
close(fdcp2[1]);
dup2(fdcp2[0], STDIN_FILENO);
execlp("./forksort", "child2", NULL);
}else {
close(fdcp2[0]);
dup2(fdcp2[1], STDOUT_FILENO);
half = (nrrows / 2);
h = half;
char b[2];
b[0] = '0' + (nrrows - h);
b[1] = '\n';
write(fdcp2[1], b, sizeof(b));
for(i = h; i < nrrows; i ++) {
rows[i][strlen(rows[i])] = '\0';
write(fdcp2[1], rows[i], sizeof(rows[i]));
}
}
}
return 0;
}
【问题讨论】:
-
这些行
pid_t chpid2 = fork(); pid_t chpid1 = fork();不会导致创建第一个孩子的额外孩子吗? chpid2 和 chpid1 将由父级创建,但另一个 chpid1 将由父级的 chpid2 创建。 -
好的,我知道。但他们 child1 仍然不会阅读。
-
抱歉,我没有时间也没有意愿深入研究代码,但可能管道刚刚被另一个孩子关闭。只需修复分叉代码并检查它是否正在修复行为。
-
@EugeneSh。我更新了我的代码并修复了导致更多孩子的问题。您现在可以看一下,因为孩子们还没有正确阅读吗?
-
使用
write()切换到低级I/O 对于您正在尝试做的事情来说并不是一个特别好的方法。有一些您没有处理的复杂情况,您可以通过使用流 I/O 来避免任何需要处理的情况。例如,您当前的问题可能与您向子进程写入的数据比您想象的要多的事实有关,其形式是每个换行符后面的空字节加上后续的垃圾。 (如果你 很幸运。)
标签: c pipe exec fork parent-child