5

値のリストdata : int listと function f: int -> unit、およびコードの一部を定義しました。

for i = 0 to (List.length data) - 1 do
  let d = List.nth data i in
  f d
done

ここで、 の最大実行時間を設定したいと思いfます。たとえばf d、一定時間を超えるmaximalと の実行がf d停止し、 の次の要素に進みdataます。

誰もそれを行う方法を知っていますか?

アップデート1:

fコメントに続いて、の要素のかなりの部分に を適用すると、例外が発生することになることを付け加えてdataおきます。これは正常であり、受け入れられます。したがって、コードは次のようになります。

List.iter
  (fun d ->
     try
       (f d)
     with
     | e ->
       printf "%s\n" (Printexc.to_string e))
data
4

2 に答える 2

5

このようなものがうまくいくかもしれません:

exception Timeout

let run_with_timeout t f x =
    try
        Sys.set_signal Sys.sigalrm (Sys.Signal_handle (fun _ -> raise Timeout));
        ignore (Unix.alarm t);
        f x;
        ignore (Unix.alarm 0);
        Sys.set_signal Sys.sigalrm Sys.Signal_default
    with Timeout -> Sys.set_signal Sys.sigalrm Sys.Signal_default

それがどのように機能するかを示すセッションは次のとおりです。

$ ocaml
        OCaml version 4.00.1

# #load "unix.cma";;
# #use "rwt.ml";;
exception Timeout
val run_with_timeout : int -> ('a -> 'b) -> 'a -> unit = <fun>
# run_with_timeout 2 Printf.printf "yes\n";;
yes
- : unit = ()
# run_with_timeout 2 (fun () -> while true do () done) ();;
- : unit = ()
#

コードは次のようになります。

List.iter (run_with_timeout 10 f) data

(このコードは十分にテストされていませんが、動作する可能性がある方法を示しています。)

アップデート

コメントが示すように、このコードはf x、例外をスローする可能性がある場合 (または他の目的でアラームを使用している場合) には適していません。gsg が改善されたソリューションを投稿することをお勧めします。編集は拒否されたようです。

于 2013-11-10T05:56:41.370 に答える
3

これは Jeffrey の回答に基づいており、例外の安全性を向上させるためにいくつかの変更が加えられています。

exception Timeout

let run_with_timeout timeout f x =
  let old_handler = Sys.signal Sys.sigalrm
    (Sys.Signal_handle (fun _ -> raise Timeout)) in
  let finish () =
    ignore (Unix.alarm 0);
    ignore (Sys.signal Sys.sigalrm old_handler) in
  try
    ignore (Unix.alarm timeout);
    ignore (f x);
    finish ()
  with Timeout -> finish ()
   | exn -> finish (); raise exn
于 2013-11-10T15:39:44.243 に答える