在OCaml或Shell中设置计时器

时间:2013-09-23 21:46:30

标签: bash shell timer makefile ocaml

我在OCaml编码了一个分析器,分析器将一个文件作为参数并返回一个评估:GOODBAD,...我有一个makefile一个接一个地在一组文件上启动分析器。

对于一些大文件,分析需要很长时间。所以我想为分析设置一个计时器:如果分析时间超过3秒,将停止对当前文件的分析,并返回TOO LONG,我们继续使用下一个文件...

有谁能告诉我在哪里添加这个计时器?围绕OCamlmakefile中的函数?怎么做?

修改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秒对于大多数分析来说太短了,所以我有

  1. 大量143,无法在0.001秒内完成分析。
  2. /bin/bash: line 10: 60202 Terminated ./analyze $f,我想当分析可以0.001秒完成时会打印出这种消息吗?
  3. /bin/bash: line 9: kill: (60241) - No such process,我想当分析可以在0.001秒完成时会打印出这种消息吗?
  4. 从字面上看,关于发生的事情,这些消息看起来仍然很奇怪......

    EDIT2:

    我使用3秒的计时器在大约4000个文件上运行分析器,因此大部分分析可以在3秒内完成。他们给了我很多像/bin/bash: line 9: kill: (60241) - No such process这样的消息。

    奇怪的是,在分析了所有文件后,终端的光标不会启动新的命令行。如果我按Ctrl+C,它将立即启动一个新的命令行。有谁知道为什么?

1 个答案:

答案 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以查看哪些程序仍在运行,但可能不应该运行。如果你可以减少我(或我们)可以重现的少量代码,那么应该很难弄清楚发生了什么并可能修复它。