我正在尝试进行两个孩子的过程以通过管道互相交流。
一个孩子应该继续从stdin阅读,将其阅读的内容传递给管道,而另一个孩子应该从管道上读取并将其打印到Stdout中。
我设法使它起作用,但是在阅读数字后的第二次迭代中只有一次,我得到了: write failed: Bad file descriptor
。
我不知道我在做什么错...
#define READ 0
#define WRITE 1
int main(){
int pipe_descs[2];
int retval = pipe(pipe_descs);
int pid = fork();
if(pid == 0){ //son that reads from stdin and writes to pipe
close(pipe_descs[READ]);
int x;
while(1){
open(pipe_descs[WRITE]);
scanf("%d", &x);
if(write(pipe_descs[WRITE], &x, sizeof(int)) != sizeof(int)){
perror("write failed");
exit(EXIT_FAILURE);
}
close(pipe_descs[WRITE]);
}
perror("");
}
else if(pid > 0){ //parent
int pid = fork();
if(pid == 0){ //son that reads from pipe and write to stdout
int pipestat;
int readNum;
close(pipe_descs[WRITE]);
while((pipestat = read(pipe_descs[READ], &readNum, sizeof(int))) > 0){
printf("read: %d n", readNum);
//close(pipe_descs[READ]);
//open(pipe_descs[READ]);
}
if (pipestat==-1) {
perror("");
fprintf(stderr, "error to pipe... exitingn");
exit(EXIT_FAILURE);
}
}
}
int status;
int i = 2;
while (i > 0){
wait(&status);
i--;
}
}
问题#1
如果您要关闭作者(close(pipe_descs[WRITE]);
),则无法继续使用它!删除该语句,或关闭管道后退出环路。
问题#2
open(pipe_descs[WRITE])
毫无意义!摆脱它。
问题#3
[如果您的系统符合POSIX.1-2001,并且您写的金额小于PIPE_BUF
,则可以忽略此部分。]
write(..., sizeof(int)) != sizeof(int)
(一定)没有指示错误条件。如果没有发生错误,则write
没有将errno
设置为有意义的事物,因此您获得的错误消息是毫无意义的。
由于write
的写入少于请求的金额不是错误,因此需要在A循环中调用它。更换
if(write(pipe_descs[WRITE], &x, sizeof(int)) != sizeof(int)){
perror("write failed");
exit(EXIT_FAILURE);
}
my_write(pipe_descs[WRITE], &x, sizeof(x));
并添加
void my_write(int fd, const void *buf, size_t bytes_to_write) {
while (bytes_to_write > 0) {
ssize_t bytes_written = write(fd, buf, bytes_to_write);
if (bytes_written == -1) {
perror("write failed");
exit(EXIT_FAILURE);
}
buf += bytes_written;
bytes_to_write -= bytes_written;
}
}
类似,read
的返回少于请求的金额不是错误。因此,还需要在A循环中调用。更换
while((pipestat = read(pipe_descs[READ], &readNum, sizeof(int))) > 0){
printf("read: %d n", readNum);
//close(pipe_descs[READ]);
//open(pipe_descs[READ]);
}
if (pipestat==-1) {
perror("");
fprintf(stderr, "error to pipe... exitingn");
exit(EXIT_FAILURE);
}
while (my_read(pipe_descs[READ], &readNum, sizeof(readNum))) {
printf("read: %d n", readNum);
}
并添加
int my_read(int fd, void *buf, size_t bytes_to_read) {
int has_read = 0;
while (bytes_to_read > 0) {
ssize_t bytes_read = read(fd, buf, bytes_to_read);
if (bytes_read == -1) {
perror("read failed");
exit(EXIT_FAILURE);
}
if (bytes_read == 0) {
if (has_read) {
fprintf(stderr, "read failed: Premature EOF");
exit(EXIT_FAILURE);
}
return 0;
}
has_read = 1;
buf += bytes_read;
bytes_to_read -= bytes_read;
}
return 1;
}