Read不会收到EOF,即使我关闭了所有管道C

Read不会收到EOF,即使我关闭了所有管道C,c,linux,fork,C,Linux,Fork,试图给出一个关于这个问题的最小可行的例子。基本上,方法send\u chars\u to\u reducers将字符发送到适当的reducer\u管道。fork\u reducers函数在收到EOF之前一直保持在while循环中,但即使我在send\u chars\u to\u reducers中关闭了所有的减速器管道,它也不会这样做。我知道它不会退出while循环,因为它从不打印退出的减速器 C代码 void发送字符到减速机(字符*行){ printf(“发送字符到减速机读取:%s\n\n”,

试图给出一个关于这个问题的最小可行的例子。基本上,方法
send\u chars\u to\u reducers
将字符发送到适当的
reducer\u管道
fork\u reducers
函数在收到EOF之前一直保持在while循环中,但即使我在
send\u chars\u to\u reducers
中关闭了所有的减速器管道,它也不会这样做。我知道它不会退出while循环,因为它从不打印退出的减速器

C代码
void发送字符到减速机(字符*行){
printf(“发送字符到减速机读取:%s\n\n”,第行);
int i;
int ob_size=1;
int-wlen=0;
对于(i=0;i=字母偏移量和行[i]<字母偏移量+字母){
int pipe_num=线[i]-α偏移量;
printf(“将%c发送到异径管%d\n”,第[i]行,管道编号);
wlen=打印(写入(异径管[pipe\u num][pipe\u write\u END],&行[i],ob\u size),“写入”);
printf(“将%s写入减速机%d\n”,第[i]行,i);
}
}
关闭异径管();
}
空心封闭管道(空心){
int i;
对于(i=0;i
全C代码
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义缓冲区大小1024
#定义ALPHA_偏移量97
#定义字母26
映射器的常数int NUM=4;
减速机的常数int NUM=26;
管道内常数读取端=0;
const int PIPE_WRITE_END=1;
const int PIPE_BUFFER_SIZE=1000;
int mapper_pipes[4][2];;
内螺纹异径管[26][2];
整数字母_计数[26];
无效初始字母计数(无效){
int i;
对于(i=0;i<26;i++){
字母计数[i]=0;
}
}
空心管道包装(int pipefd[]){
int-ret=管道(pipefd);
如果(ret==-1){
perror(“尝试创建管道时出错。”);
退出(退出失败);
}
}
void创建映射器管道(void){
int i;
对于(i=0;i=字母偏移量和行[i]<字母偏移量+字母){
int pipe_num=线[i]-α偏移量;
printf(“将%c发送到异径管%d\n”,第[i]行,管道编号);
wlen=打印(写入(异径管[pipe\u num][pipe\u write\u END],&行[i],ob\u size),“写入”);
printf(“将%c写入减速器%d\n”,第[i]行,管道编号);
}
}
printf(“循环发送字符结束”);
关闭异径管();
}
空心封闭管道(空心){
int i;
对于(i=0;i0){
//printf(“发送线到映射器读取:%s\n\n”,buff);
ob_size=buff的大小;
开关(计数){
案例0:
写入(映射器管道[0][PIPE\u write\u END],buff,ob\u size);
关闭(映射器_管道[0][PIPE_WRITE_END]);
关闭(映射器_管道[0][PIPE_READ_END]);
打破
案例1:
写入(映射器管道[1][PIPE\u write\u END],buff,ob\u size);
关闭(映射器_管道[1][PIPE_WRITE_END]);
关闭(映射器管道[1][PIPE_READ_END]);
打破
案例2:
写入(映射器管道[2][PIPE\u write\u END],buff,ob\u size);
关闭(映射器管道[2][PIPE\u WRITE\u END]);
关闭(映射器管道[2][PIPE_READ_END]);
打破
案例3:
写入(映射器管道[3][PIPE\u write\u END],buff,ob\u size);
关闭(映射器管道[3][PIPE\u WRITE\u END]);
关闭(映射器管道[3][PIPE_READ_END]);
打破
违约:
printf(“您在发送行到映射器循环中出错”);
}
计数++;
}
fclose(输入_文件);
}
内部主(空){
初始字母_
void send_chars_to_reducers(char * line) {
    printf("SEND_CHARS_TO_REDUCERS read: %s\n\n", line);
    int i;
    int ob_size = 1;
    int wlen = 0;
    for (i = 0; i < strlen(line); i++) {
        if (line[i] >= ALPHA_OFFSET && line[i] < ALPHA_OFFSET + LETTERS) {
            int pipe_num = line[i] - ALPHA_OFFSET;
            printf("SENDING %c TO REDUCER PIPE %d\n", line[i], pipe_num);
            wlen = print_if_err(write(reducer_pipes[pipe_num][PIPE_WRITE_END], &line[i], ob_size), "write");
            printf("WROTE %s to REDUCER %d\n", line[i], i);
        }
    }
    close_reducer_pipes();
}

void close_reducer_pipes(void) {
    int i;
    for (i = 0; i < NUM_OF_REDUCERS; i++) {
        close(reducer_pipes[i][PIPE_WRITE_END]);
        close(reducer_pipes[i][PIPE_READ_END]);
    }
}

void fork_mappers(void) {


    /* Constants useful to all children */
    char ibuf[PIPE_BUFFER_SIZE]; // input pipe buffer
    int rlen = 0;

    int i;
    for (i=0; i<NUM_OF_MAPPERS; i++) {
        pid_t mapper_pid = print_if_err(fork(), "fork");
        if (mapper_pid == 0) {
            int j;
            for (j=0; j < NUM_OF_MAPPERS; j++) {
                close(mapper_pipes[i][PIPE_WRITE_END]);
                if (j != i) {
                    close(mapper_pipes[j][PIPE_READ_END]);
                }
            }
            rlen = print_if_err(read(mapper_pipes[i][PIPE_READ_END], ibuf, 1000), "read");
            send_chars_to_reducers(ibuf);
            close_reducer_pipes(); 
            //printf("forked mapper%d read: %s\n\n", i, ibuf);
            close(mapper_pipes[i][PIPE_READ_END]);
            _exit(0);
        }
    }
}

void fork_reducers(void) {
    printf("HELLLOOOO FROM REDUCER\n"); 
    char ibuf[PIPE_BUFFER_SIZE]; // input pipe buffer
    int rlen = 0;
    int i;
    for (i = 0; i < NUM_OF_REDUCERS; i++) {
        pid_t reducer_pid = print_if_err(fork(), "fork");
        if (reducer_pid == 0) {
            while (1) {
                rlen = print_if_err(read(reducer_pipes[i][PIPE_READ_END], ibuf, 1), "read");
                if (rlen > 0) {
                   printf("REDUCER #%d, read %s\n", i, ibuf);
                } else {
                    break;
                }
            }       
            printf("exiting reducer\n");
            _exit(0);
        }
    }
}
#include <sys/wait.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <errno.h>

#define BUFFER_SIZE 1024
#define ALPHA_OFFSET 97
#define LETTERS 26

const int NUM_OF_MAPPERS = 4;
const int NUM_OF_REDUCERS = 26;

const int PIPE_READ_END = 0;
const int PIPE_WRITE_END = 1;
const int PIPE_BUFFER_SIZE = 1000;

int mapper_pipes[4][2];
int reducer_pipes[26][2];
int letter_count[26];

void init_letter_count(void) {
    int i;
    for (i =0; i < 26; i++) {
        letter_count[i] = 0;
    }
}

void pipe_wrapper(int pipefd[]) {
    int ret = pipe(pipefd);
    if (ret == -1) {
        perror("Error. Failed when trying to create pipes.");
        exit(EXIT_FAILURE);
    }
}

void create_mapper_pipes(void) {
    int i;
    for (i = 0; i < NUM_OF_MAPPERS; i++) {
        pipe_wrapper(mapper_pipes[i]);
    }
}

void create_reducer_pipes(void) {
    int i; 
    for (i=0; i < NUM_OF_REDUCERS; i++) {
        pipe_wrapper(reducer_pipes[i]);
    }
}

// Prints an error msg and exits if one occurs. Else, returns the system call value.
int print_if_err(int syscall_val, const char* syscall_name) {
    if (syscall_val < 0) {
        perror(syscall_name);
        exit(errno);
    } else {
        //No syscall error we can return
        return syscall_val;
    }
}

void send_chars_to_reducers(char * line) {
    printf("SEND_CHARS_TO_REDUCERS read: %s\n\n", line);
    int i;
    int ob_size = 1;
    int wlen = 0;
    for (i = 0; i < strlen(line); i++) {
        if (line[i] >= ALPHA_OFFSET && line[i] < ALPHA_OFFSET + LETTERS) {
            int pipe_num = line[i] - ALPHA_OFFSET;
            printf("SENDING %c TO REDUCER PIPE %d\n", line[i], pipe_num);
            wlen = print_if_err(write(reducer_pipes[pipe_num][PIPE_WRITE_END], &line[i], ob_size), "write");
            printf("WROTE %c to REDUCER %d\n", line[i], pipe_num);
        }
    }
    printf("END OF SEND CHAR FOR LOOP");
    close_reducer_pipes(); 
}

void close_reducer_pipes(void) {
    int i;
    for (i = 0; i < NUM_OF_REDUCERS; i++) {
        print_if_err(close(reducer_pipes[i][PIPE_WRITE_END]), "close");
        print_if_err(close(reducer_pipes[i][PIPE_READ_END]), "close");
    }
}

void fork_mappers(void) {


    /* Constants useful to all children */
    char ibuf[PIPE_BUFFER_SIZE]; // input pipe buffer
    int rlen = 0;

    int i;
    for (i=0; i<NUM_OF_MAPPERS; i++) {
        pid_t mapper_pid = print_if_err(fork(), "fork");
        if (mapper_pid == 0) {
            int j;
            for (j=0; j < NUM_OF_MAPPERS; j++) {
                close(mapper_pipes[i][PIPE_WRITE_END]);
                if (j != i) {
                    close(mapper_pipes[j][PIPE_READ_END]);
                }
            }
            rlen = print_if_err(read(mapper_pipes[i][PIPE_READ_END], ibuf, 1000), "read");
            send_chars_to_reducers(ibuf);
            //printf("forked mapper%d read: %s\n\n", i, ibuf);
            close(mapper_pipes[i][PIPE_READ_END]);
            _exit(0);
        }
    }
}

void fork_reducers(void) {
    printf("HELLLOOOO FROM REDUCER\n"); 
    char ibuf[PIPE_BUFFER_SIZE]; // input pipe buffer
    int rlen = 0;
    int i;
    for (i = 0; i < NUM_OF_REDUCERS; i++) {
        pid_t reducer_pid = print_if_err(fork(), "fork");
        if (reducer_pid == 0) {
            while (1) {
                rlen = print_if_err(read(reducer_pipes[i][PIPE_READ_END], ibuf, 1), "read");
                printf("RLEN = %d\n", rlen);
                if (rlen > 0) {
                   int letter_count_i = ibuf[0] - ALPHA_OFFSET;
                   printf("REDUCER #%d, read %s, letter_count_i = %d\n", i, ibuf, letter_count_i);
                   letter_count[letter_count_i]++;
                } else {
                    break;
                }
            }       
            printf("REDUCER EXITING\n");
            _exit(0);
        }
    }
}

void send_lines_to_mappers(void) {
    int wlen = 0;
    char obuf[PIPE_BUFFER_SIZE];
    int ob_size;
    int count = 0;

    char buff[BUFFER_SIZE]; // a buffer for each line of the file
    FILE *input_file = fopen("input.txt", "r");
    // read the input file line by line
    while(fgets(buff, BUFFER_SIZE, input_file) > 0) {
        //printf("send_lines_to_mappers read: %s\n\n", buff);
        ob_size = sizeof buff;
        switch(count) {
            case 0 :
                write(mapper_pipes[0][PIPE_WRITE_END], buff, ob_size);
                close(mapper_pipes[0][PIPE_WRITE_END]);
                close(mapper_pipes[0][PIPE_READ_END]);
                break;
            case 1 : 
                write(mapper_pipes[1][PIPE_WRITE_END], buff, ob_size);
                close(mapper_pipes[1][PIPE_WRITE_END]);
                close(mapper_pipes[1][PIPE_READ_END]);
                break;
            case 2 :
                write(mapper_pipes[2][PIPE_WRITE_END], buff, ob_size);
                close(mapper_pipes[2][PIPE_WRITE_END]);
                close(mapper_pipes[2][PIPE_READ_END]);
                break;
            case 3 : 
                write(mapper_pipes[3][PIPE_WRITE_END], buff, ob_size);
                close(mapper_pipes[3][PIPE_WRITE_END]);
                close(mapper_pipes[3][PIPE_READ_END]);
                break;
            default :
                printf("you did something wrong in send_lines_to_mappers loop");
        }
        count++;
    }
    fclose(input_file);
}

int main(void) {
    init_letter_count();
    // Setup the mapper pipes
    create_mapper_pipes();
    create_reducer_pipes();
    fork_reducers();
    fork_mappers();
    send_lines_to_mappers();

    return 0;
}
[child1] >===pipe1===> [parent] >===pipe2===> [child2]