Add process fork (albeit non-functioning)
This commit is contained in:
parent
563cced7ea
commit
446ac678db
181
cpair/cpair.c
181
cpair/cpair.c
@ -26,7 +26,9 @@
|
|||||||
* The program does the following:
|
* The program does the following:
|
||||||
* - No output if the array has one point
|
* - No output if the array has one point
|
||||||
* - The points if the array has 2 points
|
* - The points if the array has 2 points
|
||||||
* - Otherwise, the array is split in 2 parts based on the mean of X and sent to 2 different paralell child processes. The parent watches for the return code of the children and terminates with an error if any of the children exit with anything other than success.
|
* - Otherwise, the array is split in 2 parts based on the mean of X and sent to 2 different paralell child processes.
|
||||||
|
* The parent watches for the return code of the children and terminates with an error if any of the children exit
|
||||||
|
* with anything other than success.
|
||||||
*
|
*
|
||||||
* Algorithm description when there are more than 2 points:
|
* Algorithm description when there are more than 2 points:
|
||||||
* - P1 and P2 are the closest pairs for the first and the second part respectively.
|
* - P1 and P2 are the closest pairs for the first and the second part respectively.
|
||||||
@ -44,18 +46,24 @@
|
|||||||
|
|
||||||
/// Node struct for linked list
|
/// Node struct for linked list
|
||||||
typedef struct node {
|
typedef struct node {
|
||||||
|
/**
|
||||||
|
* points[0] - contains the X coordinate of the point
|
||||||
|
* points[1] - contains the Y coordinate of the point
|
||||||
|
*
|
||||||
|
**/
|
||||||
float points[2];
|
float points[2];
|
||||||
struct node * next;
|
struct node * next;
|
||||||
} node_t;
|
} node_t;
|
||||||
|
|
||||||
float get_x_mean(node_t * head);
|
float get_x_mean(node_t * head);
|
||||||
float get_distance(float x1, float x2, float y1, float y2);
|
float get_distance(float x1, float x2, float y1, float y2);
|
||||||
|
node_t * find_shortest_distance(node_t * list);
|
||||||
|
int wait_for_termination(pid_t child);
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
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;
|
||||||
pid_t child_a, child_b;
|
|
||||||
|
|
||||||
head = malloc(sizeof(node_t));
|
head = malloc(sizeof(node_t));
|
||||||
|
|
||||||
@ -74,13 +82,13 @@ int main(void) {
|
|||||||
current = current -> next;
|
current = current -> next;
|
||||||
point_num++; ///< Increase the list length
|
point_num++; ///< Increase the list length
|
||||||
} else {
|
} else {
|
||||||
puts("ERROR: Ill-formed line found");
|
fprintf(stderr, "ERROR: Ill-formed line found\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(feof(stdin) == 0) {
|
if(feof(stdin) == 0) {
|
||||||
puts("ERROR: An error interrupted the read");
|
fprintf(stderr, "ERROR: An error interrupted the read\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,35 +103,98 @@ int main(void) {
|
|||||||
|
|
||||||
float x_mean = get_x_mean(head);
|
float x_mean = get_x_mean(head);
|
||||||
|
|
||||||
child_a = fork();
|
node_t * first_part = malloc(sizeof(node_t));
|
||||||
child_b = fork();
|
node_t * second_part = malloc(sizeof(node_t));
|
||||||
|
|
||||||
switch(child_a){
|
node_t * first_part_buff = first_part;
|
||||||
|
node_t * second_part_buff = second_part;
|
||||||
|
|
||||||
|
/// Separate the lists based on the mean
|
||||||
|
current = head;
|
||||||
|
while(current != NULL) {
|
||||||
|
if(current -> points[0] <= x_mean) {
|
||||||
|
first_part_buff -> points[0] = current -> points[0];
|
||||||
|
first_part_buff -> next = malloc(sizeof(node_t));
|
||||||
|
first_part_buff = first_part_buff -> next;
|
||||||
|
} else {
|
||||||
|
second_part_buff -> points[0] = current -> points[0];
|
||||||
|
second_part_buff -> next = malloc(sizeof(node_t));
|
||||||
|
second_part_buff = second_part_buff -> next;
|
||||||
|
}
|
||||||
|
current = current -> next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the pipe file descriptors and inititalize the pipes
|
||||||
|
*
|
||||||
|
* 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) {
|
||||||
|
fprintf(stderr, "ERROR: Failed creating the pipe\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t child_a, child_b; ///< Create variables for the child processes
|
||||||
|
node_t * child_a_part = NULL;
|
||||||
|
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:
|
case -1:
|
||||||
puts("ERROR: Coudn't fork child");
|
fprintf(stderr ,"ERROR: Couldn't fork child\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
case 0:
|
case 0:
|
||||||
puts("Child");
|
if(read(pipe_a[0], child_a_part, sizeof(node_t)) < 0) {
|
||||||
|
fprintf(stderr, "ERROR: Failed reading from pipe\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
if(write(pipe_a[1], find_shortest_distance(child_a_part), sizeof(node_t)) < 0) {
|
||||||
|
fprintf(stderr, "ERROR: Failed writing to pipe\n");
|
||||||
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(child_b){
|
|
||||||
case -1:
|
|
||||||
puts("ERROR: Coudn't fork child");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
case 0:
|
|
||||||
puts("Child");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int status;
|
if(wait_for_termination(child_a) != EXIT_SUCCESS)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
waitpid(child_a, &status, 0);
|
if(wait_for_termination(child_b) != EXIT_SUCCESS)
|
||||||
waitpid(child_b, &status, 0);
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
/// Free the memory
|
||||||
|
free(head);
|
||||||
|
free(first_part);
|
||||||
|
free(first_part_buff);
|
||||||
|
free(second_part);
|
||||||
|
free(second_part_buff);
|
||||||
|
free(current);
|
||||||
|
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
@ -138,14 +209,15 @@ int main(void) {
|
|||||||
float get_x_mean(node_t * head) {
|
float get_x_mean(node_t * head) {
|
||||||
node_t * current = head;
|
node_t * current = head;
|
||||||
float x_sum = 0;
|
float x_sum = 0;
|
||||||
int i = 0;
|
int i = 1;
|
||||||
while(current -> next != NULL) {
|
|
||||||
|
while(current != NULL) {
|
||||||
x_sum += current -> points[0];
|
x_sum += current -> points[0];
|
||||||
current = current -> next;
|
current = current -> next;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return x_sum/i;
|
return x_sum/(i - 2); ///< TODO: Fix the bug with the 2 more iterations
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -160,3 +232,64 @@ float get_x_mean(node_t * head) {
|
|||||||
float get_distance(float x1, float x2, float y1, float y2) {
|
float get_distance(float x1, float x2, float y1, float y2) {
|
||||||
return sqrt(pow((x2 - x1), 2) + pow((y2 - y1), 2));
|
return sqrt(pow((x2 - x1), 2) + pow((y2 - y1), 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function to find the shortest distance in a list
|
||||||
|
* @details The function gets a list of points and finds the pair
|
||||||
|
* with the shortest distance between them.
|
||||||
|
* @param list - the list with points
|
||||||
|
* @return res - a list containing the coordinates of the two closest points
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
node_t * find_shortest_distance(node_t * list) {
|
||||||
|
node_t * current = list;
|
||||||
|
node_t * next = list;
|
||||||
|
|
||||||
|
/// Setup the result list
|
||||||
|
node_t * res = malloc(sizeof(node_t));
|
||||||
|
res -> next = malloc(sizeof(node_t));
|
||||||
|
|
||||||
|
int current_shortest = 0;
|
||||||
|
int new_shortest = 0;
|
||||||
|
|
||||||
|
while(current != NULL) {
|
||||||
|
next = current -> next;
|
||||||
|
if(next != NULL) {
|
||||||
|
new_shortest = get_distance(current -> points[0], next -> points[0], current -> points[1], next -> points[1]);
|
||||||
|
|
||||||
|
if(new_shortest < current_shortest) {
|
||||||
|
current_shortest = new_shortest;
|
||||||
|
|
||||||
|
/// Save the pairs
|
||||||
|
res -> points[0] = current -> points[0];
|
||||||
|
res -> points[1] = current -> points[1];
|
||||||
|
res -> next -> points[0] = next -> points[0];
|
||||||
|
res -> next -> points[1] = next -> points[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
current = next;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @briefs Function that waits for a child to close
|
||||||
|
* @details The function waits for a child to close.
|
||||||
|
* If it closes successfully, it returns the exit status only.
|
||||||
|
* Otherwise, it prints an error message and then returns the exit status.
|
||||||
|
* @param child - the pid of the child process
|
||||||
|
* @return the exist status of the child process
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
int wait_for_termination(pid_t child) {
|
||||||
|
int exit_stat = 0;
|
||||||
|
|
||||||
|
if(waitpid(child, &exit_stat, 0) < 0) {
|
||||||
|
fprintf(stderr, "ERROR: Child did not exit successfully\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return WEXITSTATUS(exit_stat);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user