我在OCaml
编码了一个分析器,分析器将一个文件作为参数并返回一个评估:GOOD
,BAD
,...我有一个makefile
一个接一个地在一组文件上启动分析器。
对于一些大文件,分析需要很长时间。所以我想为分析设置一个计时器:如果分析时间超过3秒,将停止对当前文件的分析,并返回TOO LONG
,我们继续使用下一个文件...
有谁能告诉我在哪里添加这个计时器?围绕OCaml
或makefile
中的函数?怎么做?
修改:makefile
的一部分:
allev: all
@n=0; \
for f in \
`find . -ipath '*/fetch/evs/*.ev' -exec grep -L -e "' Error" {} \;`; \
do \
let "n+=1"; \
echo "oooooooooooooooooooooooooooooooooooooooo" $$n; \
echo $$f; \
./$(BIN) $$f & \
PID=$$!; \
(sleep 0.001; kill $$PID) & \
wait $$PID; \
echo $$?; \
done
实际上0.001
秒对于大多数分析来说太短了,所以我有
143
,无法在0.001
秒内完成分析。/bin/bash: line 10: 60202 Terminated ./analyze $f
,我想当分析可以不在0.001
秒完成时会打印出这种消息吗?/bin/bash: line 9: kill: (60241) - No such process
,我想当分析可以在0.001
秒完成时会打印出这种消息吗?从字面上看,关于发生的事情,这些消息看起来仍然很奇怪......
EDIT2:
我使用3
秒的计时器在大约4000个文件上运行分析器,因此大部分分析可以在3
秒内完成。他们给了我很多像/bin/bash: line 9: kill: (60241) - No such process
这样的消息。
奇怪的是,在分析了所有文件后,终端的光标不会启动新的命令行。如果我按Ctrl+C
,它将立即启动一个新的命令行。有谁知道为什么?
答案 0 :(得分:0)
如果您想在OCaml中执行此操作,最终可能会使用Unix
模块中的定时器和信号。或者,如果你愿意,你可以使用bash中的相同信号和计时器。
以下是运行<program>
的一些bash代码,以便在<N>
秒后如果它在那时没有完成则会被终止。
<program> &
PID=$!
(sleep <N>; kill $PID) &
wait $PID
echo $?
您的程序应使用小于126的退出代码;否则他们会与bash使用的值发生冲突。假设您遵循此约定,$?
的值大于128表示程序被信号杀死。 (对于此特定代码,您应该看到值143.)小于126的值表示您的程序退出了它自己的自由意志。
信号很难做到正确,我只测试了几次这段代码。我希望它有用。
<强>更新强>
这是一个包含上述代码的Makefile,其中包含程序和超时的具体替换。
testrun: myprogram
myprogram & \
PID=$$! ; \
(sleep 3; kill $$PID) & \
wait $$PID ; \
echo $$?
如果你不熟悉make(1),这可能看起来很疯狂。要注意的要点是(A)需要在第一个命令行的开头有一个实际的TAB字符; (B)需要在除最后一个命令行之外的所有命令行的末尾使用\
(以在单个shell中运行所有命令); (C)需要将命令与;
或&
分开(因为shell将其视为一条长行); (D)当您需要$$
时需要使用$
,因为$
是特殊的。我对此进行了测试,它对我有用。
如果你没有兴趣去解决make和bash的语法复杂性,你可能想在OCaml中这样做。
更新2
我不确定你最后会看到什么导致暂停。几乎可以肯定的是等待它已经启动的程序,并且该程序由于某种原因没有退出。您可以运行ps
以查看哪些程序仍在运行,但可能不应该运行。如果你可以减少我(或我们)可以重现的少量代码,那么应该很难弄清楚发生了什么并可能修复它。