#pipe #duplex #child-process #ipc #multiprocessing #communication-channel

viaduct

使用无名称管道在父进程和子进程之间建立一个全双工通信通道

3 个不稳定版本

0.4.0 2022年8月18日
0.3.1 2022年8月7日
0.2.1 2022年8月7日
0.1.0 2022年8月5日

#320 in 内存管理

MIT/Apache

53KB
1K SLoC

crates.io docs.rs license

Viaduct 是一个库,用于在父进程和子进程之间通过无名称管道建立一个全双工通信通道。

示例

共享库

#[derive(Serialize, Deserialize)]
pub enum ExampleRpc {
    Cow,
    Pig,
    Horse
}

#[derive(Serialize, Deserialize)]
pub enum ExampleRequest {
    DoAFrontflip,
    DoABackflip,
}

#[derive(Serialize, Deserialize, PartialEq, Eq)]
pub struct FrontflipError;

#[derive(Serialize, Deserialize, PartialEq, Eq)]
pub struct BackflipError;

父进程

let child = std::process::Command::new("child.exe");
let ((tx, rx), mut child) = ViaductParent::new(child).unwrap().build().unwrap();

std::thread::spawn(move || {
    rx.run(
        |rpc: ExampleRpc| match rpc {
            ExampleRpc::Cow => println!("Moo"),
            ExampleRpc::Pig => println!("Oink"),
            ExampleRpc::Horse => println!("Neigh"),
        },

        |request: ExampleRequest, tx| match request {
            ExampleRequest::DoAFrontflip => {
                println!("Doing a frontflip!");
                tx.respond(Ok::<_, FrontflipError>(())).unwrap();
            },

            ExampleRequest::DoABackflip => {
                println!("Doing a backflip!");
                tx.respond(Ok::<_, BackflipError>(())).unwrap();
            },
        },
    ).unwrap();
});

tx.rpc(ExampleRpc::Cow).unwrap();
tx.rpc(ExampleRpc::Pig).unwrap();
tx.rpc(ExampleRpc::Horse).unwrap();

let response: Result<(), FrontflipError> = tx.request(ExampleRequest::DoAFrontflip).unwrap();
assert_eq!(response, Ok(()));

子进程

let (tx, rx) = unsafe { ViaductChild::new() }.unwrap();

std::thread::spawn(move || {
    rx.run(
        |rpc: ExampleRpc| match rpc {
            ExampleRpc::Cow => println!("Moo"),
            ExampleRpc::Pig => println!("Oink"),
            ExampleRpc::Horse => println!("Neigh"),
        },

        |request: ExampleRequest, tx| match request {
            ExampleRequest::DoAFrontflip => {
                println!("Doing a frontflip!");
                tx.respond(Ok::<_, FrontflipError>(())).unwrap();
            },

            ExampleRequest::DoABackflip => {
                println!("Doing a backflip!");
                tx.respond(Ok::<_, BackflipError>(())).unwrap();
            },
        },
    ).unwrap();
});

tx.rpc(ExampleRpc::Horse).unwrap();
tx.rpc(ExampleRpc::Pig).unwrap();
tx.rpc(ExampleRpc::Cow).unwrap();

let response: Result<(), BackflipError> = tx.request(ExampleRequest::DoABackflip).unwrap();
assert_eq!(response, Ok(()));

使用场景

Viaduct 被设计用于以跨平台的方式分离用户界面和应用逻辑。

例如,一个应用程序可能希望在单独的进程中运行GUI,以实现模块化或性能原因。

Viaduct 允许此类应用程序以自然的方式在这些进程之间进行通信,而无需手动实现IPC机制和同步。

使用方法

有关使用信息,请参阅文档

许可证

Viaduct 可根据您的选择,在MIT许可证或Apache许可证v2.0下获得许可。

依赖关系

~1–37MB
~557K SLoC