gpt4 book ai didi

在 fork 进程中调用读取不起作用 (Linux C)

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

这里是 C 初学者。我正在尝试读取我的 reducer_pipesfork_reducer方法,但是当我调用 read , read 下没有任何内容被执行。如果我不打电话 read它确实被执行了。 read 方法似乎没有打印任何错误消息。

C代码

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

最佳答案

您需要将 read 移动到 while (1) 循环中:

        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);
}

}

关于在 fork 进程中调用读取不起作用 (Linux C),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35369752/

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