0
尝试回答练习时,我遇到了问题,这需要第一个进程逐行写入管道,第二个进程从缓冲区读取该管道只有20个字节。似乎有些信息在管道中“丢失”,并且输入中缺少初始消息的随机位。下面是有关该问题的代码:将管道重复读入小缓冲区的问题
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define BUFF_SIZE 20
#define LINE_SIZE 150
int main(){
pid_t idp1, idp2;
int pipefd[2];
if (pipe(pipefd) == -1) return 3; //Pipe error
if ((idp1 = fork()) == 0){
//SON 1
close(pipefd[0]);
FILE* input = fopen("input.txt", "r");
char line[LINE_SIZE];
//Get a line
while(fgets(line, LINE_SIZE, input)){
//Sends the line
write(pipefd[1], line, LINE_SIZE);
sleep(1);
}
fclose(input);
close(pipefd[1]);
}else if(idp1 != -1){
if ((idp2 = fork()) == 0){
//SON 2
close(pipefd[1]);
char inMsg[BUFF_SIZE] = "";
int received;
while(received = read(pipefd[0], inMsg, BUFF_SIZE)){
inMsg[received] = '\0';
printf("%.*s", received, inMsg);
}
}else if(idp2 != -1){
//Father
close(pipefd[0]);
close(pipefd[1]);
//SleepOrWhatever();
}else return 2; //Fork 2 error
}else return 1; //Fork 1 error
return 0;
}
现在,通过添加延迟(每行的进入管道的输入之后休眠)时,它解决了上述问题。这是为什么 ?无论如何要避免这种情况?下面是结果与睡眠和无壳:
[010][input.txt]
[049][[Fichier d'entrée du programme TD0 forkpipe.c].]
[001][]
[054][[003]Il contient des lignes [de longueurs variables].]
[041][avec des lignes blanches (longuer [000])]
[001][]
[009][d'autres]
[020][ commencant]
[036][ par des blancs.]
[010][et enfin,]
[021][une dernière ligne.]
[010][input.txt]
hier d'entrée du programme TD0 forkpipe.c].]
[001][]
]Il contient des lignes [de longueurs variables].]
[041][avec des lignes blanches (longuer [000])]
[009][d'autres]
commencant]
[036][ par des blancs.]
nfin,]
[021][une dernière ligne.]
PS:我也试图与从管道更大的缓冲区大小,一切输出精确的读取。如果它对管道的行为有任何重要性,我也运行在Linux发行版上。
工作就像一个魅力,我会期待写在字符串的结尾停止。你有什么想法为什么它在睡眠中工作? –
睡眠工作最有可能是垃圾是所有的空让第二个进程有足够的时间清空管道缓冲区(并且printf没有打印所有NULL字节)。至于缺少一些字节的文本,考虑20字节边界是否以NULL终止的垃圾字节开始,例如“'\ 0'mystsring”。然后printf会忽略这一点,并丢弃你的真实数据。 – Milan