gpt4 book ai didi

scala - scala.sys.process 是否阻塞流处理线程?

转载 作者:行者123 更新时间:2023-12-04 01:17:36 24 4
gpt4 key购买 nike

Scala 外部进程库 scala.sys.process 允许运行外部进程(例如 ls)并附加一些处理stdoutstderr 函数。例如:

Seq("ls" ".").run(new ProcessIO(os => os.close(), is => f(is), is => g(is))).exitValue()

这会运行 ls . 并在其 stdoutstderr 上运行一些函数 fg 。文档说 fg 在不同的线程中执行。

我的问题是,.exitValue() 会一直阻塞直到 ls 退出,或者直到不仅 ls 退出而且那些线程也退出运行 fg 完成了吗?

最佳答案

一个简单的实验:

def doStuff(sleepFor: Long): Unit = {
val startTime = System.currentTimeMillis
val result = Seq("ls", ".").run(
new ProcessIO(
{ os: OutputStream => os.close() },
{ is: InputStream => Thread.sleep(sleepFor); is.close() },
{ is: InputStream => Thread.sleep(sleepFor); is.close() }
)
).exitValue
val finishTime = System.currentTimeMillis
println(s"Result = $result, took ${ finishTime - startTime }ms")
}

调用时,如果我们看到它至少花费了 sleepForms,它几乎肯定会阻塞,直到标准输出和标准错误上的函数完成(特别是如果这适用于两个非常不同的值sleepFor).

在 SBT 控制台中:

scala> doStuff(1000)
Result = 0, took 1002ms

scala> doStuff(10000)
Result = 0, took 10002ms

实验验证 .run().exitValue 阻塞,直到输入和输出的功能完成。

Tracing through the source (截至 2.13,但更早的版本应该类似),我们看到 Seq[String] 最终创建了一个 Simple ProcessBuilder,当运行导致 SimpleProcess :

override def exitValue() = {
try p.waitFor() // wait for the process to terminate
finally interrupt()
outputThreads foreach (_.join()) // this ensures that all output is complete before returning (waitFor does not ensure this)

p.exitValue()

标准输出/错误处理器线程位于 outputThreads 中并被joined,它会阻塞直到两个线程都完成。

旁注:scala.sys.process 是标准库中大多数古老 API 的有力竞争者,因为它早于 Future API 的引入并且导致流/惰性输出行列表的函数将退出代码编码为裸RuntimeException,其中必须解析消息以提取退出代码(而不是可区分的异常或更好的异常) Either[ExitWithErrorException, String] 的流。

关于scala - scala.sys.process 是否阻塞流处理线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63092469/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com