Справочная информация:
У меня есть процесс, использующий tokio::process
для порождения дочерних процессов с дескрипторами во время выполнения Tokio.
Он также отвечает за освобождение ресурсов после уничтожения child и, согласно документации ( std :: process :: Child , tokio :: process :: Child ), для этого требуется родительский элемент wait()
(или await
в tokio) для процесса.
Не все процессы ведут себя одинаково с SIGINT
или SIGTERM
, поэтому я хотел дать ребенку некоторое время для d ie, прежде чем отправлять 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
снова, если время истекло?
Примечание:
Я решил свою непосредственную проблему, установив таймер Токио, который всегда отправляет * 10 42 * через две секунды и один self.process.await
внизу. Но это решение нежелательно, так как другой процесс может появляться в том же PID во время работы таймера.
Редактировать:
Добавление минимального Воспроизводимый пример ( детская площадка )
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;
}
}