我有一個Rust行程,它應該啟動一個子行程,然后立即退出。這似乎可以作業:
fn main() {
//Intentionally drop the return Child and exit。
Command::new("bash")。 args(&["-c", "sleep 10s; touch done"]) 。 spawn().unwrap()。
}
運行這個行程立即退出,bash行程繼續進行:
$ cargo build; target/debug/demo
$ ps aux | grep bash
dimo414 35959 0.0 0. 0 4278616 1484 S001 S 1: 12PM 0:00. 00 bash -c sleep 10s; touch done
...
然而如果我再加一層,試圖呼叫我的二進制檔案并等待其完成,這似乎也是在等待子行程,與我在 shell 中觀察到的不同。下面是一個MCVE:
fn main() {
let exec = std::env::current_exe() 。 expect("Could not resolve executable location") 。
//首先重新呼叫同一個二進制并等待它。
if std::env::args().len() < 2{
println! ("Ran Subprocess:
{:?}", Command::new(exec).arg(")。 output().unwrap()。
} else {
//在該子行程中產生一個長期運行的行程,但不要等待。
println!("Spawning Subprocess") 。
Command::new("bash")。 args(&["-c", "sleep 10s; touch done"]) 。 spawn().unwrap()。
}
$ cargo build; target/debug/demo
# 不不終止,直到bash行程終止。
有沒有一種方法可以讓頂層行程完成而不等待嵌套行程?
uj5u.com熱心網友回復:
請檢查spawn的reference。
作為一個子行程執行命令,回傳一個句柄給它。
默認情況下,stdin、stdout和stderr都是從父行程中繼承的。
當你作為一個子行程運行 self 時,它產生了另一個子行程,并從父行程繼承了 stdio。由于你的頂層行程使用了output(),它將等待子行程完成并收集其所有的output(reference)。
讓我們這樣來演示:
Root -> Sub1 -> Sub2
Sub2 使用 Sub1 的 stdout 通道,Root 等待收集 Sub1 的所有輸出,而 Sub2 仍在使用,最后 Root 等待 Sub2 結束。
解決方案是;簡單地使用Stdio::null()來發送輸出到/dev/null,因為你的 Root 行程并不關心 Sub2 的輸出。
fn main() {
let exec = std::env::current_exe() 。 expect("Could not resolve executable location") 。
if std::env::args().len() < 2{
println!(
"Ran Subprocess:
{:?}"。
命令::new(exec).arg("") 。 output().unwrap()
);
} else {
println!("Spawning Subprocess") 。
Command::new("bash")
.stdout(Stdio::null()
.stderr(Stdio::null()
.args(&["-c"/span>, "sleep 10s; touch done"])
.spawn()
.unwrap()。
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/318108.html
標籤:
上一篇:ocrsync由于/tmp存盤的磁盤上沒有空間而失敗
下一篇:如何在unix中打開現有的腳本
