【发布时间】:2019-12-20 22:21:39
【问题描述】:
我试图理解 C 语言中的 pipe、fork 和 exec,因此我尝试编写一个小程序,该程序接受一个输入字符串并在 2 个同时运行的子进程的帮助下将其打印出来。
由于代码太长,我将其发布在此链接中:https://pastebin.com/mNcRWkDg,我将用作参考。我还在底部发布了我的代码的简短版本
示例应该如何处理输入abcd:
> ./echo
abcd
result ->
abcd
我正在通过getline() 输入并检查input_lengh 是否是偶数或可以分成偶数部分。如果它只是一个char,它只会打印出来。
如果它是例如abcd,即有4个input_length,它将在struct parts的帮助下将其分成两部分first_partab和second_partcd,如下所示:
struct parts p1;
split(input, &p1);
然后我为第一个孩子设置pipe,为它设置fork,然后为第二个孩子设置相同的设置。我将第一个孩子output 重定向为父进程的输入,第二个孩子也是如此。让我们假设该部分按应有的方式工作。
然后我把它写到他们的子进程输入:
write(pipeEndsFirstChild2[1], p1.first_half, strlen(p1.first_half));
write(pipeEndsSecondChild2[1], p1.second_half, strlen(p1.second_half));
之后我用fdopen()打开他们的输出并用fgets()阅读它
最后我分配内存并连接两个结果:
char *result = malloc(strlen(readBufFirstChild) + strlen(readBufSecondChild));
strcat(result, readBufFirstChild);
strcat(result, readBufSecondChild);
我使用stderr 查看输出,因为stdout 被重定向,我得到的是:
>./echo
abcd
result ->
cd
result ->
ab
result ->
����
问题:
如何让子进程 1 先给我ab,然后再让第二个子给我cd,即如何确保子进程以正确的顺序运行?由于我只打印如何在进程之间保存ab 和cd 并将它们连接到父进程中以将它们输出到stdout?
如果我尝试:
>./echo
ab
result ->
ab
一切都按预期工作,所以我想如果我必须像abcd 输入那样多次调用子进程,那么事情就会变得一团糟。为什么?
int main(int argc, char *argv[])
{
int status = 0;
char *input;
input = getLine();
int input_length = strlen(input);
if((input_length/2)%2 == 1 && input_length > 2)
{
usage("input must have even length");
}
if (input_length == 1)
{
fprintf(stdout, "%s", input);
}else
{
struct parts p1;
split(input, &p1);
int pipeEndsFirstChild1[2];
int pipeEndsFirstChild2[2];
.
.
.
pid_t pid1 = fork();
redirectPipes(pid1, pipeEndsFirstChild1, pipeEndsFirstChild2);
int pipeEndsSecondChild1[2];
int pipeEndsSecondChild2[2];
.
.
.
pid_t pid2 = fork();
redirectPipes(pid2, pipeEndsSecondChild1, pipeEndsSecondChild2);
// write to 1st and 2nd child input
write(pipeEndsFirstChild2[1], p1.first_half, strlen(p1.first_half));
write(pipeEndsSecondChild2[1], p1.second_half, strlen(p1.second_half));
.
.
.
// open output fd of 1st child
FILE *filePointer1 = fdopen(pipeEndsFirstChild1[0], "r");
// put output into readBufFirstChild
fgets(readBufFirstChild,sizeof(readBufFirstChild),filePointer1);
// open output fd of 2nd child
FILE *filePointer2 = fdopen(pipeEndsSecondChild1[0], "r");
// open output fd of 2st child
fgets(readBufSecondChild,sizeof(readBufSecondChild),filePointer2);
//concat results
char *result = malloc(strlen(readBufFirstChild) +
strlen(readBufSecondChild) + 1);
strcpy(result, readBufFirstChild);
strcat(result, readBufSecondChild);
fprintf(stderr, "result ->\n%s\n", result);
if(wait(&status) == -1){
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
}
【问题讨论】:
-
请从链接中复制代码的相关部分。有些人不能/不想访问外部链接。
-
@AjayBrahmakshatriya 我在帖子底部添加了它。
-
为什么需要
buf和buf2?您可以直接从p1.first_half和p1.second_half写信。 -
子进程将同时运行,但没关系。您首先从第一个孩子开始阅读,因此您应该以正确的顺序获得结果。
-
@Barmar 正如我在上面的输出中所示,我先得到 cd,然后得到 ab。这不是正确的顺序。