在使用半自动化 Judge 系统对同学的答题进行评测的时候,遇到了一个奇怪的问题,总是会提示: Test_1: output.txt: openFile: resource busy (file is locked)


起初以为是 haskell 惰性求值导致的 IO 问题,因为搜索引擎也把猜测引导向这个原因,但是始终解决不了。


后来改变了思路,“现在看来好像是模块引入带来的 main 函数重名问题”,这是后面的猜疑。


继而发现将函数改名字也解决不了问题,实际也不是,就是 IO 的问题。因为如果先移除 output.txt, 那么使用 ghc 执行就不会出现之前的错误提示,不过在 ghci 中执行总是不会出错。

使用如下代码测试一下:

dir = "/home/user-name/Downloads/auto_check/work/2015final/ref/tests/words"

main :: IO ()
main = do print "hehe"
solution = runTest
         (map (\f -> combine dir f) ["input1-1.txt", "input1-2.txt", "input1-3.txt"])
         (combine dir "output1.txt")
`</pre>

执行得到如下结果:

<pre>`➜  test  ghci Test_1.hs
GHCi, version 7.8.4: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[1 of 3] Compiling Main             ( Main.hs, interpreted )
[2 of 3] Compiling FileBasedTest    ( FileBasedTest.hs, interpreted )
[3 of 3] Compiling Test             ( Test_1.hs, interpreted )
Ok, modules loaded: Test, FileBasedTest, Main.
*Test&gt; main
Loading package array-0.5.0.0 ... linking ... done.
Loading package deepseq-1.3.0.2 ... linking ... done.
Loading package old-locale-1.0.0.6 ... linking ... done.
Loading package time-1.4.2 ... linking ... done.
Loading package bytestring-0.10.4.0 ... linking ... done.
Loading package unix-2.7.0.1 ... linking ... done.
Loading package filepath-1.3.0.2 ... linking ... done.
Loading package directory-1.2.1.0 ... linking ... done.
"hehe"
*Test&gt; 
Leaving GHCi.
➜  test  rm Test_1.hi
➜  test  ghc Test_1.hs -o Test_1
[3 of 3] Compiling Test             ( Test_1.hs, Test_1.o )
Linking Test_1 ...
➜  test  ./Test_1 
Test_1: output.txt: openFile: resource busy (file is locked)
➜  test  

可以看到直接执行 ghc 编译得到的二进制文件就会出现问题,而在 ghci 中就不会。


经过了一些过程之后终于修复,根本原因是,整个项目的程序入口是 test01.hs 中 Test 模块的 main 函数,而引入了同学实现的代码中的 Main 模块,导致 ghc 编译的时候使用 Main 模块中的 main 函数作为入口。最后通过指定那个模块中的 main 函数作为入口解决: ghc -main-is Test.main Test_1.hs -o Test_1