gpt4 book ai didi

rust - 通过Tokio UnixStream与子进程进行通信

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

我正在尝试使父进程和子进程使用Tokio UnixStream相互通信。问题在于,由于某种原因, child 无法读取任何 parent 将其写入套接字的内容(大概是相反的情况)。

我具有的功能与以下类似

    pub async fn run() -> Result<(), Error> {
let mut socks = UnixStream::pair()?;

match fork() {
Ok(ForkResult::Parent { .. }) => {
socks.0.write_u32(31337).await?;
Ok(())
}

Ok(ForkResult::Child) => {
eprintln!("Reading from master");
let msg = socks.1.read_u32().await?;
eprintln!("Read from master {}", msg);
Ok(())
}
Err(_) => Err(Error),
}
}

套接字不会关闭,否则尝试从 socks.1读取时会出现立即错误。如果我将读入父进程,它将按预期工作。第一行 Reading from master被打印,但第二行从未被调用。

我无法更改通信范例,因为我将使用 execve启动另一个期望与 socketpair对话的二进制文件。

知道我在这里做错了什么吗?与 async函数生成的 await/ async状态机有关吗?

最佳答案

当您调用fork()系统调用时:

The child process is created with a single thread—the one that called fork().



tokio中的默认执行程序是线程池执行程序。子进程将仅获得池中的线程之一,因此它将无法正常工作。

我发现我可以通过将线程池设置为仅包含一个线程来使您的程序正常工作,如下所示:
use tokio::prelude::*;
use tokio::net::UnixStream;
use nix::unistd::{fork, ForkResult};
use nix::sys::wait;
use std::io::Error;
use std::io::ErrorKind;
use wait::wait;

// Limit to 1 thread
#[tokio::main(core_threads = 1)]
async fn main() -> Result<(), Error> {
let mut socks = UnixStream::pair()?;

match fork() {
Ok(ForkResult::Parent { .. }) => {
eprintln!("Writing!");
socks.0.write_u32(31337).await?;
eprintln!("Written!");
wait().unwrap();
Ok(())
}

Ok(ForkResult::Child) => {
eprintln!("Reading from master");
let msg = socks.1.read_u32().await?;
eprintln!("Read from master {}", msg);
Ok(())
}

Err(_) => Err(Error::new(ErrorKind::Other, "oh no!")),
}
}

我必须进行的另一项更改是通过调用 wait()来迫使父级等待子级完成-这也是您可能不希望在真正的异步程序中执行的操作。

我读过的大多数建议中,如果您需要从线程程序中派生,请在创建任何线程之前执行此操作,或者在 fork 后立即在子级中调用 exec_ve()(无论如何,您都打算这样做)。

关于rust - 通过Tokio UnixStream与子进程进行通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60686516/

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