我正在尝试使用进程实现合并排序,但是使用waitpid
函数遇到问题:
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();
}
}
我得到这些结果而没有使用
waitpid
作为矢量[3, 70, 97, 74]
:比较之前的
[3, 70, 97, 74]
比较:
[97]
,[74]
比较后的数组:
[3, 70, 74, 97]
[3, 70, 97, 74]
比较:
[3]
,[70]
比较后的数组:
[3, 70, 97, 74]
[3, 70, 97, 74]
比较:
[3, 70]
, [97, 74]
(应为[74, 97]
)比较后的数组:
[3, 70, 97, 74]
最佳答案
这与waitpid
无关,与fork
无关。当您派生一个进程时,操作系统将创建您的数据的副本,并且子代操作该副本1。当子代退出时,其内存将被丢弃。 parent 永远不会看到 child 所做的更改。
如果您需要 parent 查看 child 所做的更改,则应执行以下一项操作:
mmap
或等效的方法在父进程和子进程之间共享内存。但是请注意,当所有进程都尝试同时访问同一内存时,要确保内存安全将非常困难。 mmap
更容易,因为在内存访问期间没有发生冲突的风险,但是在您的情况下,鉴于需要发送的数据量,这将是最慢的。 1 实际上,它使用“写时复制”,因此可以共享简单读取的数据,但是父或子写的任何内容都将被复制,而另一个不会看到写结果。
关于linux - 如何使用 `waitpid`等待Rust中的进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59296406/