Rework children creation and add recursive calls

This commit is contained in:
Ivaylo Ivanov 2018-12-15 18:45:22 +01:00
parent 446ac678db
commit c70db7363d

View File

@ -60,7 +60,28 @@ float get_distance(float x1, float x2, float y1, float y2);
node_t * find_shortest_distance(node_t * list); node_t * find_shortest_distance(node_t * list);
int wait_for_termination(pid_t child); int wait_for_termination(pid_t child);
int main(void) { int main(int argc, char *argv[]) {
if (argc > 1) {
puts("The command takes no additional arguments.");
puts("Usage: cpair");
exit(EXIT_FAILURE);
}
fprintf(stderr, "Process id: %d\n", getpid());
/**
* Create the pipe file descriptors and inititalize the pipes
*
* fd[0] - input side of pipe
* fd[1] - output side of pipe
*
**/
int in_pipe_a[2], out_pipe_a[2], in_pipe_b[2], out_pipe_b[2];
if(pipe(in_pipe_a) < 0 || pipe(in_pipe_b) < 0 || pipe(out_pipe_a) < 0 || pipe(out_pipe_b) < 0) {
fprintf(stderr, "ERROR: Failed creating the pipes\n");
exit(EXIT_FAILURE);
}
char input[__UINT8_MAX__] = ""; ///< An array to save the input to char input[__UINT8_MAX__] = ""; ///< An array to save the input to
int point_num = 0; ///< Save the number of points int point_num = 0; ///< Save the number of points
node_t * head = NULL; node_t * head = NULL;
@ -101,10 +122,61 @@ int main(void) {
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
pid_t child_a, child_b; ///< Create variables for the child processes
/// Create first child
switch(child_a = fork()) {
case -1:
fprintf(stderr ,"ERROR: Couldn't fork child\n");
exit(EXIT_FAILURE);
case 0:
/// Child execution
fprintf(stderr, "Child 1 id: %d\n", getpid());
close(out_pipe_a[0]);
close(in_pipe_a[1]);
close(STDIN_FILENO);
if(dup2(in_pipe_a[0], STDIN_FILENO) != STDIN_FILENO) {
fprintf(stderr, "ERROR: Failed duplicating STDIN");
exit(EXIT_FAILURE);
}
execlp(argv[0], argv[0], NULL);
fprintf(stderr, "ERROR: Failed to load program into child");
exit(EXIT_FAILURE);
default:
/// Parent execution
/// Create second child
switch(child_b = fork()) {
case -1:
fprintf(stderr, "ERROR: Couldn't fork child\n");
exit(EXIT_FAILURE);
case 0:
/// Child execution
fprintf(stderr, "Child 2 id: %d\n", getpid());
close(out_pipe_b[0]);
close(in_pipe_b[1]);
close(STDIN_FILENO);
if(dup2(in_pipe_b[0], STDIN_FILENO) != STDIN_FILENO) {
fprintf(stderr, "ERROR: Failed duplicating STDIN");
exit(EXIT_FAILURE);
}
execlp(argv[0], argv[0], NULL);
fprintf(stderr, "ERROR: Failed to load program into child");
exit(EXIT_FAILURE);
default:
/// Parent execution
close(in_pipe_a[0]);
close(in_pipe_b[0]);
close(STDOUT_FILENO);
float x_mean = get_x_mean(head); float x_mean = get_x_mean(head);
node_t * first_part = malloc(sizeof(node_t)); node_t * first_part = malloc(sizeof(node_t));
int first_part_len = 1;
node_t * second_part = malloc(sizeof(node_t)); node_t * second_part = malloc(sizeof(node_t));
int second_part_len = 1;
node_t * first_part_buff = first_part; node_t * first_part_buff = first_part;
node_t * second_part_buff = second_part; node_t * second_part_buff = second_part;
@ -116,77 +188,48 @@ int main(void) {
first_part_buff -> points[0] = current -> points[0]; first_part_buff -> points[0] = current -> points[0];
first_part_buff -> next = malloc(sizeof(node_t)); first_part_buff -> next = malloc(sizeof(node_t));
first_part_buff = first_part_buff -> next; first_part_buff = first_part_buff -> next;
first_part_len ++;
} else { } else {
second_part_buff -> points[0] = current -> points[0]; second_part_buff -> points[0] = current -> points[0];
second_part_buff -> next = malloc(sizeof(node_t)); second_part_buff -> next = malloc(sizeof(node_t));
second_part_buff = second_part_buff -> next; second_part_buff = second_part_buff -> next;
second_part_len ++;
} }
current = current -> next; current = current -> next;
} }
/** /**
* Create the pipe file descriptors and inititalize the pipes * Send the correct lists to the children
*
* fd[0] - input side of pipe
* fd[1] - output side of pipe
*
**/ **/
int pipe_a[2], pipe_b[2];
if(pipe(pipe_a) < 0 || pipe(pipe_b) < 0) { /// First half
fprintf(stderr, "ERROR: Failed creating the pipe\n"); if(dup2(in_pipe_a[1], STDIN_FILENO) != STDIN_FILENO) {
fprintf(stderr, "ERROR: Failed duplicating STDIN");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
pid_t child_a, child_b; ///< Create variables for the child processes if (write(in_pipe_a[1], first_part_buff, first_part_len*sizeof(node_t)) < 0) {
node_t * child_a_part = NULL; fprintf(stderr, "ERROR: Failed writing to child\n");
node_t * child_b_part = NULL;
write(pipe_a[0], first_part, sizeof(node_t)); ///< Send the first part of the array to the child
switch(child_a = fork()) {
case -1:
fprintf(stderr ,"ERROR: Couldn't fork child\n");
exit(EXIT_FAILURE);
case 0:
if(read(pipe_a[0], child_a_part, sizeof(node_t)) < 0) {
fprintf(stderr, "ERROR: Failed reading from pipe\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if(write(pipe_a[1], find_shortest_distance(child_a_part), sizeof(node_t)) < 0) { close(STDOUT_FILENO);
fprintf(stderr, "ERROR: Failed writing to pipe\n"); ///Second half
if(dup2(in_pipe_b[1], STDIN_FILENO) != STDIN_FILENO) {
fprintf(stderr, "ERROR: Failed duplicating STDIN");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
exit(EXIT_SUCCESS);
break;
default:
write(pipe_b[0], second_part, sizeof(node_t));
switch(child_b = fork()) {
case -1:
fprintf(stderr, "ERROR: Couldn't fork child\n");
exit(EXIT_FAILURE);
case 0:
if(read(pipe_b[0], child_b_part, sizeof(node_t)) < 0) {
fprintf(stderr, "ERROR: Failed reading from pipe\n");
exit(EXIT_FAILURE);
}
if(write(pipe_b[1], find_shortest_distance(child_b_part), sizeof(node_t)) < 0) {
fprintf(stderr, "ERROR: Failed writing to pipe\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
break;
default:
break;
}
break;
}
if(wait_for_termination(child_a) != EXIT_SUCCESS) if (write(in_pipe_b[1], first_part_buff, second_part_len*sizeof(node_t)) < 0) {
fprintf(stderr, "ERROR: Failed writing to child\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
}
close(STDOUT_FILENO);
if(wait_for_termination(child_b) != EXIT_SUCCESS) /// Wait for the correct exit of the children
if(wait_for_termination(child_a) != EXIT_SUCCESS || wait_for_termination(child_b) != EXIT_SUCCESS) {
fprintf(stderr, "ERROR: Children didn't terminate successfully");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
}
/// Free the memory /// Free the memory
free(head); free(head);
@ -195,6 +238,9 @@ int main(void) {
free(second_part); free(second_part);
free(second_part_buff); free(second_part_buff);
free(current); free(current);
break;
}
}
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }