确定。以下代码有效。并且,它在Akka演员中起作用。但是,当扩展线程数(即几百个)时,它会因文本文件忙而崩溃。
过程是。我将一个shell脚本写入磁盘,然后设置其执行位。紧接着,我通过ProcessBuilder运行脚本。
import better.files._ // uses nio
// this occurs in an actor, many are running in parallel
val f = File(pathToFile)
f.overwrite(contentsofScript)
f.addPermission(PosixFilePermissions.OWNER_EXECUTE)
val p = Process(pathToFile)
p.! // execute IT!
每个进程都指向文件系统中唯一且随机的位置(pathToFile)。
我很难理解为什么代码不能很好地扩展。
Caused by: java.io.IOException: error=26, Text file busy
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.<init>(UNIXProcess.java:247)
at java.lang.ProcessImpl.start(ProcessImpl.java:134)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
... 26 more
此answer描述了JDK中的错误或可能未封闭的I / O流。在启动进程之前,我正在使用带有.close()和.flush()调用的传统PrintWriter。我在运行进程之前尝试打开并读取文件的内容(希望关闭资源)。我搬到了better.files._
,希望能更好地处理资源。
https://stackoverflow.com/editing-help
ulimit -n
提供65000(最大打开文件)。
答案 0 :(得分:1)
不。我是个白痴。我做出的这个断言是错误的:
每个进程都指向文件系统中唯一且随机的位置(pathToFile)。
我的代码中没有发生这种情况的固定角落情况(运行了数千个线程,生成了重复的随机UUID,因此重复的进程触及相同的目录)
编辑:上面只是部分相关...
可能存在JDK错误(由java executing bash script, error=26 Text file busy提供)
https://bugs.openjdk.java.net/browse/JDK-8068370
..以下代码更改解决了问题..
val p = Process(Seq("bash", pathToFile))
p.!
答案 1 :(得分:0)
我想知道您是否遇到竞争条件,执行该文件时您的文件写入内容未同步。
在阅读有关此答案的第一条评论时,我想到了这一点:https://stackoverflow.com/a/16764967/7760212
然后我看了better-files
,写完后关闭文件似乎很干净。但是,在您的情况下,似乎传递给java.nio.Files.*
的选项可能会更安全一些。我建议尝试为openOptions
调用的overwrite
参数传递非默认值。您可以在此处阅读这些选项:https://docs.oracle.com/javase/7/docs/api/java/nio/file/StandardOpenOption.html,但我建议您将StandardOpenOption.SYNC
添加到默认的better-files
集。“