Я использую tokio 0.2.21 и futures 0.3.5 и rust c stable 1.43.1
Я использую futures :: future :: Abortable для обертывания tokio :: process: : Команда, чтобы я мог прервать процесс из другой задачи tokio.
Я понимаю, что:
Unix требует, чтобы родители процесса подтвердили завершение дочернего процесса одним из нескольких механизмы. tokio :: process :: unix :: Child был изменен таким образом, что при удалении экземпляра вызывается kill (), которая убивает дочерний процесс, но не вызывает try_wait или wait, поскольку эти вызовы могут блокировать. Была создана глобальная очередь процессов, которые нужно "пожать" путем вызова try_wait.
Что у меня есть псевдо-код sh -код:
async fn do_work() {
// Spawn the child command
let child = Command::new("sleep").args(&["30"]).spawn();
// Move the child in to a future that waits for the child to complete and is wrapped in an Abortable
let (abort_handle, abort_registration) = AbortHandle::new_pair();
let child_fut = Abortable::new(async move {
let status = child.await;
println!("Child exited with status: {}", status);
Ok::<_, Aborted>(())
}, abort_registration);
// Create a future that aborts the child future after a delay
let delay_fut = async {
delay_for(Duration::from_secs(2)).await;
abort_handle.abort();
Ok(())
};
// Wait for both to complete or one future to error
tokio::try_join!(child_fut, delay_fut);
}
async fn main() {
loop {
do_work().await;
delay_for(Duration::for_secs(10)).await;
}
}
Что я хочу:
Я хочу прервать Command / Child и убить процесс unix. Это работает.
Я также хочу, чтобы unix завершился процесс. В конце концов это произойдет, но не раньше, чем завершится еще одна итерация delay_for, произойдет еще одна итерация основного l oop и снова будет вызвана do_work ().
Вопрос:
Я знаю, что если мой try_join обнаруживает ошибку Aborted, то дочерний процесс был прерван и завершен. Могу ли я вручную принудительно запустить глобальную дочернюю очередь-сирот, чтобы дочерний процесс unix был получен в конце do_work ()?
Или мне следует принять поведение по умолчанию? Но я хотел бы знать, как обеспечить, чтобы после завершения do_work () завершился несуществующий процесс.
Дополнительная информация:
Я увидел кое-что странное. Я запустил отладочную сборку в lldb. Когда я добавляю точку останова для tokio / src / process / unix / reap.rs: 136 в impl Drop for Reaper fn drop (). Если я немедленно продолжу работу отладчика, я вижу, что неработающий процесс unix выполняется немедленно, до main () delay_for (Duration :: from_secs (10)). Когда я запускаю код вне отладчика, я вижу, что дочерний элемент defunt получен после main () delay_for.
Я использую проект по умолчанию с car go new. Я добавил зависимости для tokio 0.2.21, но никаких дополнительных настроек не делал. Я использую сборку автомобиля go, сборку отладки.
Спасибо за ваше время и идеи.