背景:
我有一个使用tokio::process
的进程,它在时雄运行时中生成带有句柄的子进程。
它还负责在杀死子进程后释放资源,根据文档(std::process::Child,时雄::process::Child),这需要父进程为进程wait()
(或时雄中的await
)。
并不是所有的进程对SIGINT
或SIGTERM
的行为都是一样的,所以我想在发送SIGKILL
之前给予子进程一些时间。
所需解决方案:
pub async fn kill(self) {
// Close input
std::mem::drop(self.stdin);
// Send gracefull signal
let pid = nix::unistd::Pid::from_raw(self.process.id() as nix::libc::pid_t);
nix::sys::signal::kill(pid, nix::sys::signal::SIGINT);
// Give the process time to die gracefully
if let Err(_) = tokio::time::timeout(std::time::Duration::from_secs(2), self.process).await
{
// Kill forcefully
nix::sys::signal::kill(pid, nix::sys::signal::SIGKILL);
self.process.await;
}
}
然而,这个错误是:
error[E0382]: use of moved value: `self.process`
--> src/bin/multi/process.rs:46:13
|
42 | if let Err(_) = tokio::time::timeout(std::time::Duration::from_secs(2), self.process).await
| ------------ value moved here
...
46 | self.process.await;
| ^^^^^^^^^^^^ value used here after move
|
= note: move occurs because `self.process` has type `tokio::process::Child`, which does not implement the `Copy` trait
如果我服从并删除self.process.await
,我会看到子进程仍然占用ps
中的资源。
问题:
如何在一段时间内执行await
,并在时间到期后再次执行操作和await
?
注:
我解决了我眼前的问题,设置了一个时雄计时器,总是在两秒钟后发送SIGKILL
,并在底部有一个单一的self.process.await
。但是这种解决方案并不理想,因为当计时器运行时,另一个进程可能会在同一个PID中产生。
- 编辑:*
添加minimal, reproducible example(playground)
async fn delay() {
for _ in 0..6 {
tokio::time::delay_for(std::time::Duration::from_millis(500)).await;
println!("Ping!");
}
}
async fn runner() {
let delayer = delay();
if let Err(_) = tokio::time::timeout(std::time::Duration::from_secs(2), delayer).await {
println!("Taking more than two seconds");
delayer.await;
}
}
2条答案
按热度按时间wfauudbj1#
你需要传递一个可变的引用。但是,您首先需要固定future,以便其可变引用实现Future。pin_mut从futures crate重新导出是一个很好的帮手:
nom7f22z2#
对于以下情况,可以重用通用 Package 器: