在调用read在派生进程不工作(Linux下C) [英] Calling read in forked process not working (Linux C)

查看:128
本文介绍了在调用read在派生进程不工作(Linux下C)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Ç初学者在这里。我试图从读我的 reducer_pipes fork_reducer 方法,但是当我打电话,下没什么<$​​ C $ C>读被执行。如果我不叫它得到执行。读出方法不可能在打印任何错误消息。

C $ C $ç

 的#include&LT; SYS / wait.h&GT;
#包括LT&;&stdbool.h GT;
#包括LT&;&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&unistd.h中GT;
#包括LT&;&string.h中GT;
#包括LT&;&time.h中GT;
#包括LT&;&errno.h中GT;的#define BUFFER_SIZE 1024
#定义ALPHA_OFFSET 97
#定义快报26const 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];
诠释reducer_pipes [26] [2];无效pipe_wrapper(INT pipefd []){
    INT RET =管(pipefd);
    如果(RET == -1){
        PERROR(错误尝试创建管道时失败。);
        出口(EXIT_FAILURE);
    }
}无效create_mapper_pipes(无效){
    INT I;
    对于(i = 0; I&LT; NUM_OF_MAPPERS;我++){
        pipe_wrapper(mapper_pipes [I]);
    }
}无效create_reducer_pipes(无效){
    INT I;
    对于(i = 0; I&LT; NUM_OF_REDUCERS;我++){
        pipe_wrapper(reducer_pipes [I]);
    }
}//打印错误味精如果发生退出。否则,返回系统调用值。
INT print_if_err(INT syscall_val,为const char * syscall_name){
    如果(syscall_val℃,){
        PERROR(sy​​scall_name);
        退出(错误);
    }其他{
        //没有系统调用的错误,我们可以返回
        返回syscall_val;
    }
}无效send_chars_to_reducers(字符*线){
    的printf(send_chars_to_reducers阅读:%S \\ n \\ n,行);
    INT I;
    INT ob_size = 2;
    对于(i = 0; I&LT;的strlen(线);我++){
        如果(行[I]&GT; = ALPHA_OFFSET和放大器;&放大器;线[1] - ; ALPHA_OFFSET +字母){
            写(reducer_pipes [行[I] -ALPHA_OFFSET] [PIPE_WRITE_END],线[I],ob_size);
        }
    }
}无效close_reducer_pipes(无效){
    INT I;
    对于(i = 0; I&LT; NUM_OF_REDUCERS;我++){
        关闭(reducer_pipes [I] [PIPE_WRITE_END]);
        关闭(reducer_pipes [I] [PIPE_READ_END]);
    }
}无效fork_mappers(无效){
    / *向所有儿童有益的常量* /
    烧焦IBUF [PIPE_BUFFER_SIZE] //输入管道缓冲区
    INT RLEN = 0;    INT I;
    对于(i = 0; I&LT; NUM_OF_MAPPERS;我++){
        将为pid_t mapper_pid = print_if_err(fork()的叉);
        如果(mapper_pid == 0){
            诠释J;
            为(J = 0; J&LT; NUM_OF_MAPPERS; J ++){
                关闭(mapper_pipes [I] [PIPE_WRITE_END]);
                如果(J!=ⅰ){
                    关闭(mapper_pipes [J] [PIPE_READ_END]);
                }
            }
            RLEN = print_if_err(读(mapper_pipes [I] [PIPE_READ_END],IBUF,1000),读);
            send_chars_to_reducers(IBUF);
            close_reducer_pipes();
            的printf(分叉映射%d个读:%S \\ n \\ n,我,IBUF);
            关闭(mapper_pipes [I] [PIPE_READ_END]);
            _exit(0);
        }
    }
}无效fork_reducers(无效){
    的printf(HELLLOOOO从减速\\ n);
    烧焦IBUF [PIPE_BUFFER_SIZE] //输入管道缓冲区
    INT RLEN = 0;
    INT I;
    对于(i = 0; I&LT; NUM_OF_REDUCERS;我++){
        将为pid_t reducer_pid = print_if_err(fork()的叉);
        如果(reducer_pid == 0){
            的printf(减速子\\ n的内部);
            RLEN = print_if_err(读(reducer_pipes [I] [PIPE_READ_END],IBUF,1000),读);
            而(1){
                的printf(你好,从而减速while循环);                如果(RLEN大于0){
                   的printf(减速#%D,读%S \\ n,我,IBUF);
                }            }
        }
    }
}无效send_lines_to_mappers(无效){
    INT WLEN = 0;
    烧焦OBUF [PIPE_BUFFER_SIZE]
    INT ob_size;
    诠释计数= 0;    字符的buff [BUFFER_SIZE]; //为文件的每一行的缓冲区
    FILE * INPUT_FILE =的fopen(input.txt的,R);
    //逐行读取输入文件行
    而(与fgets(BUFF,BUFFER_SIZE,INPUT_FILE)0){
        的printf(send_lines_to_mappers阅读:%S \\ n \\ n,浅黄色);
        ob_size = sizeof的爱好者;
        开关(计数){
            情况下0:
                写(mapper_pipes [0] [PIPE_WRITE_END],浅黄色,ob_size);
                关闭(mapper_pipes [0] [PIPE_WRITE_END]);
                关闭(mapper_pipes [0] [PIPE_READ_END]);
                打破;
            情况1 :
                写(mapper_pipes [1] [PIPE_WRITE_END],浅黄色,ob_size);
                关闭(mapper_pipes [1] [PIPE_WRITE_END]);
                关闭(mapper_pipes [1] [PIPE_READ_END]);
                打破;
            案例2:
                写(mapper_pipes [2] [PIPE_WRITE_END],浅黄色,ob_size);
                关闭(mapper_pipes [2] [PIPE_WRITE_END]);
                关闭(mapper_pipes [2] [PIPE_READ_END]);
                打破;
            案例3:
                写(mapper_pipes [3] [PIPE_WRITE_END],浅黄色,ob_size);
                关闭(mapper_pipes [3] [PIPE_WRITE_END]);
                关闭(mapper_pipes [3] [PIPE_READ_END]);
                打破;
            默认情况下:
                的printf(你做错了什么在send_lines_to_mappers回路);
        }
        算上++;
    }
    FCLOSE(INPUT_FILE);
}诠释主要(无效){
    //设置映射器管
    create_mapper_pipes();
    create_reducer_pipes();
    fork_reducers();
    fork_mappers();
    send_lines_to_mappers();    返回0;
}


解决方案

您需要移动里面的而(1)循环:

 而(1){
            的printf(你好,从而减速while循环);            RLEN = print_if_err(读(reducer_pipes [I] [PIPE_READ_END],IBUF,1000),读);
            如果(RLEN大于0){
               的printf(减速#%D,读%S \\ n,我,IBUF);
            }        }

C beginner here. I'm trying to read from my reducer_pipes in the fork_reducer method, but when I call read, nothing under the read gets executed. If I don't call read it does get executed. The read method does not appear to be printing any error messages.

C Code

#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];

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 = 2;
    for (i = 0; i < strlen(line); i++) {
        if (line[i] >= ALPHA_OFFSET && line[i] < ALPHA_OFFSET + LETTERS) {
            write(reducer_pipes[line[i]-ALPHA_OFFSET][PIPE_WRITE_END], line[i], ob_size);
        }
    }
}

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) {
            printf("inside reducer child\n");
            rlen = print_if_err(read(reducer_pipes[i][PIPE_READ_END], ibuf, 1000), "read");
            while (1) {
                printf("hello from while reducer while loop");

                if (rlen > 0) {
                   printf("reducer #%d, read %s\n", i, ibuf);
                } 

            }       
        }
    }
}

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) {
    // Setup the mapper pipes
    create_mapper_pipes();
    create_reducer_pipes();
    fork_reducers();
    fork_mappers();
    send_lines_to_mappers();

    return 0;
}

解决方案

You need to move the read inside of the while (1) loop:

        while (1) {
            printf("hello from while reducer while loop");

            rlen = print_if_err(read(reducer_pipes[i][PIPE_READ_END], ibuf, 1000), "read");
            if (rlen > 0) {
               printf("reducer #%d, read %s\n", i, ibuf);
            } 

        }       

这篇关于在调用read在派生进程不工作(Linux下C)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆