gpt4 book ai didi

c - 将管道重复读入小缓冲区的问题

转载 作者:太空宇宙 更新时间:2023-11-04 11:12:44 26 4
gpt4 key购买 nike

我在尝试回答一个练习时遇到了一个问题,它要求第一个进程逐行写入管道,第二个进程从只有 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;

}

现在,通过添加延迟(每行输入到管道后的 sleep ),它解决了问题。这是为什么 ?无论如何要避免这种情况?这是在有 sleep 和没有 sleep 的 shell 中的结果:

[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 发行版上运行,如果它对管道的行为有任何重要性的话。

最佳答案

考虑从文件读取输入时发生了什么,即:

//Get a line
while(fgets(line, LINE_SIZE, input)){ <<-- fgets reads a line _up_ to a LINE_SIZE bytes (and the result will be null terminated)


//Sends the line
write(pipefd[1], line, LINE_SIZE); <<-- Write LINE_SIZE bytes to the pipe
}

因此,给定文件中的几行,您可以阅读例如使用 fgets 60 字节,然后将 150 字节写入管道(这意味着 90 字节的垃圾也会进入管道)。

你最终得到这个:

输入:

first line
second line
third line

管道数据:

first line***second line*** third line ***

其中*** 表示写入管道的垃圾数据。一旦第二个进程开始读取,根据垃圾数据,它可能会打印它想要的任何内容。

关于c - 将管道重复读入小缓冲区的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22349208/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com