跳转至

Rust进程通信-管道

Rust进程通信-管道

Cargo.toml

[package]
name = "test_rust"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
nix = "0.24.1"

main.rs

use nix;
use std::thread;
use std::fs;
use std::io::{Read, Write};

static PATH: &str = "./my_pipe";

fn main(){
    // 初始化测试文件
    let _ = fs::remove_file(PATH);
    if let Err(_e) = nix::unistd::mkfifo(PATH, nix::sys::stat::Mode::S_IRWXU) {
        panic!("出错了! {_e}")
    }

    // 线程1 循环读取管道
    // 在管道未写入数据时, 是无法打开文件, 也无法从管道中读取到数据
    thread::spawn(|| {
        println!("开始读取信息");
        let mut f = fs::File::open(PATH).unwrap();
        let mut buffer = [0; 128];

        loop {
            let _ = f.read(&mut buffer);
            let c_str = unsafe {std::ffi::CStr::from_ptr(buffer.as_ptr() as *mut _)};
            println!("读取到信息 {:?}", c_str);
        };
    });

    thread::sleep(std::time::Duration::from_secs(3));

    // 线程2 每秒循环写入管道
    thread::spawn(|| {
        let mut f = fs::OpenOptions::new()
            .write(true)
            .open(PATH)
            .unwrap();
        let mut cnt = 0;
        let mut buffer = String::new();
        loop {
            buffer = format!("hello {cnt}");
            println!("准备写入: {buffer}");
            let _ = f.write_all(buffer.as_bytes());
            thread::sleep(std::time::Duration::from_secs(1));
            cnt += 1;
        }
    });

    println!("ctrl + c 退出");
    nix::unistd::pause();
}