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

标签 linux process rust waitpid

我正在尝试使用进程实现合并排序,但是使用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/

    相关文章:

    r - 使用odbc在R studio Session中从MS sql server读写时出现问题

    perl - 如何确定 Java 进程是否在 Perl 中运行

    gcc - 如何在 Rust 中使用 -mlongcall GCcflags?

    rust - 闭包需要对 lambda 函数的唯一访问

    linux - 使用 sed 在两个模式之间打印

    c++ - 更改 ld-linux 位置

    php - Python 将数据 POST 到 Linux 上的本地 PHP

    c - 零线程进程?

    c++ - 当进程在 linux 下结束时如何得到通知?

    asynchronous - 如何在 Actix-web 中的 WebSocket 处理程序中正确调用异步函数