运行带有超时的命令
我正在将命令行程序从 Python 翻译为 Rust。
该程序必须运行无法终止的不同命令。
Python 版本使用 subprocess.run()
接受 timeout
作为参数。
例如:
result = subprocess.run(["java", "MyProgram"],
timeout=timeout,
capture_output=True)
当翻译成 Rust 时,我使用:
let out = Command::new("java")
.arg("MyProgram")
.output()?;
但据我所知,Command 不允许我指定任何超时。
由于它将在 GNU/Linux 上运行,我可以简单地用 timeout
包装调用(如 timeout 10 java MyProgram
),但我想知道是否有任何不依赖于的解决方案超时。
所以问题是:如何在 Rust 中运行超时命令?
I'm translating a command line program from Python to Rust.
The program has to run different commands that could not terminate.
The Python version uses subprocess.run()
that accepts timeout
as argument.
For example:
result = subprocess.run(["java", "MyProgram"],
timeout=timeout,
capture_output=True)
When translating into Rust, I'm using:
let out = Command::new("java")
.arg("MyProgram")
.output()?;
But as long as I know, Command is not allowing me to specify any timeout.
Since it will run on GNU/Linux, I could simply wrap the call with timeout
(as in timeout 10 java MyProgram
) but I wonder if there's any solution that does not depend on timeout
.
So the question is: how do I run a command from Rust with a timeout?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
有几种方法可以解决这个问题。
一种方法是启动后台线程并使用
Child::kill()
在超时后终止进程。您需要使用 Arc 在线程之间共享对象。但这有点问题,因为Child
的方法需要对Child
的可变引用,因此您不能同时从一个线程等待该进程你试图从另一个人那里杀死它。另一种方法是在自旋循环中使用Child::try_wait(),并在挂钟超过阈值时间时终止进程。
或者,考虑使用 wait_timeout 包,它将这种复杂性包装在一个简单的函数后面。
There's a few ways you could handle this.
One would be to start a background thread and use
Child::kill()
to kill the process after a timeout. You would need to useArc
to share the object between threads. This is a bit problematic though because the methods ofChild
require a mutable reference to theChild
, so you can't wait on the process from one thread at the same time as you try to kill it from another.Another approach would be to use
Child::try_wait()
in a spinloop and kill the process when the wall clock has passed a threshold time.Alternatively, consider using the
wait_timeout
crate, which wraps up this complexity behind a simple function.简短回答:
如果像我一样,由于使用
SIG_CHLD
而无法使用wait_timeout
箱,那么您可能有兴趣使用child_wait_timeout
,没有这个限制(我是这个箱子的作者)。长答案:
我知道这个问题已经很老了,我只想对已接受的答案发表评论,但我对此没有足够的声誉。
我在搜索如何在 Rust 中执行 wait_timeout 时偶然发现了这个问题。在我的情况下,
wait_timeout
箱由于使用SIG_CHLD
而无法使用。经过一番研究,我发现了另外两种在 Rust 中实现异步wait_timeout
的方法:pidfd_open
。pthread_cancel
。这些实现可在
child_wait_timeout
箱 (https://docs.rs /child_wait_timeout/latest/child_wait_timeout/)。所有这些方法都是异步的,并且与使用信号的方法类似,开销可以忽略不计(板条箱中提供了基准)。
Short answer:
If, like me, you cannot use the
wait_timeout
crate due to its use ofSIG_CHLD
, you might be interested in usingchild_wait_timeout
, which doesn't have this limitation (I am the author of this crate).Long answer:
I know this question is quite old, and I only wanted to comment on the accepted answer, but I do not have enough reputation for it.
I stumbled upon this question while searching for how to perform a
wait_timeout
in Rust. In my situation, thewait_timeout
crate is not usable due to its use ofSIG_CHLD
. After some research, I found two other ways to implement an asyncwait_timeout
in Rust:pidfd_open
.pthread_cancel
.These implementations are available in the
child_wait_timeout
crate (https://docs.rs/child_wait_timeout/latest/child_wait_timeout/).All these methods are asynchronous and have negligible overhead similarly to the method that use signal (benchmark available in the crate).