gpt4 book ai didi

linux - 如何使用 `waitpid`等待Rust中的进程?

转载 作者:行者123 更新时间:2023-12-03 11:43:43 24 4
gpt4 key购买 nike

我正在尝试使用进程实现合并排序,但是使用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 所做的更改,则应执行以下一项操作:

  • 最简单,最快的方法是使用线程而不是进程。线程共享内存,因此父级和子级都使用相同的内存。在Rust中,借位检查器可确保父级和子级在访问同一块内存时行为正确。
  • 使用 mmap 或等效的方法在父进程和子进程之间共享内存。但是请注意,当所有进程都尝试同时访问同一内存时,要确保内存安全将非常困难。
  • 使用某种进程间通信(IPC)机制将结果从子级发送回父级。这比mmap更容易,因为在内存访问期间没有发生冲突的风险,但是在您的情况下,鉴于需要发送的数据量,这将是最慢的。

  • 1 实际上,它使用“写时复制”,因此可以共享简单读取的数据,但是父或子写的任何内容都将被复制,而另一个不会看到写结果。

    关于linux - 如何使用 `waitpid`等待Rust中的进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59296406/

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