2016-01-31 2 views
2

Я попытался создать поток, который вычисляет число фибоначчи. Это работало нормально, но затем я попытался создать еще один поток, который останавливает поток вычислений, если для вычисления требуется больше, чем x секунд.Thread Calculation OCaml

Вот мой код:

module TimedFuture : sig 
    type 'a t 
    val create : ('a -> 'b) -> 'a -> float -> 'b t 
    val get : 'a t -> 'a option 
end = struct 

type 'a t = 'a Event.channel 

let create f a t = 
let c = Event.new_channel() in 
let rec loop f = f(); loop f in 
let task() = 
    let b = f a in 
    loop (fun() -> Event.(sync (send c b))) 
in 
let start_calc_thread() = 
    let t1 = Thread.create task() in 
    while ((Unix.gettimeofday() -. t) < 1.0) do 
    Printf.printf "Thread should keep running: %f\n" 
        (Unix.gettimeofday() -. t); 
    done; 
    try Thread.kill t1 with t1 ->(); 
    Printf.printf "Thread stoped\n" 
in 
let _ = Thread.create start_calc_thread() in 
c 

let get c = Some Event.(sync (receive c)) 
end 


let option_to_i o = match o with 
       | None -> 0 
       | Some x -> x 

let test = 
let rec f x = match x with 
      | 1 -> 1 
      | 2 -> 1 
      | _ -> f (x-1) + f (x-2) 
in 
let t = Unix.gettimeofday() in 
let ff = TimedFuture.create f 40 t in 
Printf.printf "\nResult: %i\n" (option_to_i (TimedFuture.get ff)), 
ff 

Когда я скомпилировать код и запустить его, расчет потока не перестает работать, хотя я получаю «Thread остановился» в терминале.

Вы видите мою вину?

+0

Вы игнорируете ошибки Thread.kill, так как попробуйте Thread.kill t1 с t1 ->(); 'Было бы интересно посмотреть в ошибке - BTW Зачем вызывать исключение t1? См. Также http://stackoverflow.com/questions/35001959/interrupt-a-call-in-ocaml –

ответ

0

Поток может быть прерван только в определенных точках отмены, в частности, в точках, когда пользовательский код передает управление обратно во время выполнения, чтобы последний мог выполнять свою работу. Одной конкретной точкой отмены является выделение. Поскольку ваш код не выделяется, и разумно реализованный Fibonacci не будет выделяться, его невозможно остановить. Если ваш реальный алгоритм действительно не имеет точек отмены, то вы должны либо добавить их явно, либо использовать процессы. Чтобы добавить точную точку отмены, можно просто добавить Thread.yield.