I am trying to implement a merge sort using processes but I have a problem using the waitpid
function:
extern crate nix;
extern crate rand;
use nix::sys::wait::WaitStatus;
use rand::Rng;
use std::io;
use std::process::exit;
use std::thread::sleep;
use std::time::{Duration, Instant};
use nix::sys::wait::waitpid;
use nix::unistd::Pid;
use nix::unistd::{fork, getpid, getppid, ForkResult};
static mut process_count: i32 = 0;
static mut thread_count: i32 = 0;
fn generate_array(len: usize) -> Vec<f64> {
let mut my_vector: Vec<f64> = Vec::new();
for _ in 0..len {
my_vector.push(rand::thread_rng().gen_range(0.0, 100.0)); // 0 - 99.99999
}
return my_vector;
}
fn get_array_size_from_user() -> usize {
let mut n = String::new();
io::stdin()
.read_line(&mut n)
.expect("failed to read input.");
let n: usize = n.trim().parse().expect("invalid input");
return n;
}
fn display_array(array: &mut Vec<f64>) {
println!("{:?}", array);
println!();
}
fn clear_screen() {
print!("{}[2J", 27 as char);
//print!("\x1B[2J"); // 2nd option
}
pub fn mergeSort(a: &mut Vec<f64>, low: usize, high: usize) {
let middle = (low + high) / 2;
let mut len = (high - low + 1);
if (len <= 1) {
return;
}
let lpid = fork();
match lpid {
Ok(ForkResult::Child) => {
println!("Left Process Running ");
mergeSort(a, low, middle);
exit(0);
}
Ok(ForkResult::Parent { child }) => {
let rpid = fork();
match rpid {
Ok(ForkResult::Child) => {
println!("Right Process Running ");
mergeSort(a, middle + 1, high);
exit(0);
}
Ok(ForkResult::Parent { child }) => {}
Err(err) => {
panic!("Right process not created: {}", err);
}
};
}
Err(err) => {
panic!("Left process not created {}", err);
}
};
//waitpid(lpid, None);
//waitpid(rpid, None);
// Merge the sorted subarrays
merge(a, low, middle, high);
}
fn merge(a: &mut Vec<f64>, low: usize, m: usize, high: usize) {
println!("x");
let mut left = a[low..m + 1].to_vec();
let mut right = a[m + 1..high + 1].to_vec();
println!("left: {:?}", left);
println!("right: {:?}", right);
left.reverse();
right.reverse();
for k in low..high + 1 {
if left.is_empty() {
a[k] = right.pop().unwrap();
continue;
}
if right.is_empty() {
a[k] = left.pop().unwrap();
continue;
}
if right.last() < left.last() {
a[k] = right.pop().unwrap();
} else {
a[k] = left.pop().unwrap();
}
}
println!("array: {:?}", a);
}
unsafe fn display_process_thread_counts() {
unsafe {
println!("process count:");
println!("{}", process_count);
println!("thread count:");
println!("{}", thread_count);
}
}
unsafe fn process_count_plus_plus() {
process_count += 1;
}
unsafe fn thread_count_plus_plus() {
thread_count += 1;
}
fn print_time(start: Instant, end: Instant) {
println!("TIME:");
println!("{:?}", end.checked_duration_since(start));
}
fn main() {
println!("ENTER SIZE OF ARRAY \n");
let array_size = get_array_size_from_user();
let mut generated_array = generate_array(array_size);
clear_screen();
println!("GENERATED ARRAY: \n");
display_array(&mut generated_array);
// SORTING
let start = Instant::now();
mergeSort(&mut generated_array, 0, array_size - 1);
let end = Instant::now();
// RESULT
//unsafe{
// process_count_plus_plus();
// thread_count_plus_plus();
//}
println!("SORTED ARRAY: \n");
display_array(&mut generated_array);
print_time(start, end);
unsafe {
display_process_thread_counts();
}
}
I get these results without using waitpid
for the vector [3, 70, 97, 74]
:
array before comparison:
[3, 70, 97, 74]
comparison:
[97]
,[74]
array after comparison:
[3, 70, 74, 97]
array before comparison:
[3, 70, 97, 74]
comparison:
[3]
,[70]
array after comparison:
[3, 70, 97, 74]
array before comparison:
[3, 70, 97, 74]
comparison:
[3, 70]
,[97, 74]
(should be[74, 97]
)array after comparison:
[3, 70, 97, 74]