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