Ocaml:Thread.delay没有像我预期的那样工作

时间:2012-12-08 20:37:35

标签: multithreading class ocaml process

我正在为一个班级项目开发一个小型反导弹模拟器。

理念是让不同的流程/线程相互交流。

我开始研究Missile Laucher应用程序。它的导弹必须是一个线程。

所以这是我做的开始代码:

open Missile;;

(* Name of the Station *)
let launcher_name = "Pacific";;

(* Gravitational Constant *)
let g = 9.8;;

(* Temporal Reference *)
let time = ref 0.0;;

(* Calculates the next position in time of the missile *)
let calculate_position () = 
  let nX = 10.0 *. !time and nY = (0.5) *. g**2.0 in (nX,nY);;

(* Launches the thread missile and updates its position *)
let launch mis = 
  while true do 

    let pos = mis#position () in 
    Printf.printf "%s\n" pos;


    let (a,b) = calculate_position () in
    mis#moveto (a,b);
    time := !time +. 1.0;

    (* Why isnt this working? *)
    Thread.delay 0.25 

  done;;



(* test function *)
let launchMissile () = 
  Printf.printf "Launch Station %s launched a missile. \n" launcher_name;
  let mis  = new missile "Test" 1 "USA" in
  let t1 = Thread.create launch mis in
  Thread.join t1;;



launchMissile ();;

执行此操作后,我想通过随时间打印值来测试我的CalculatePosition函数。

但是没有停顿或等待,他们打印得太快,显然。所以我考虑在每次迭代时将线程延迟0.25秒。

我做错了什么?我尝试了很多不同的东西。它唯一的Thread.delay函数表现得很奇怪。

我可以这样做吗?

如果你能提供帮助就会很棒,我已经没想过了......并开始重读我在Ocaml上的所有书籍。

如果你在这里分析问题也很重要,那就是我的导弹课程:

class missile name id owner = 
object
  val mutable name = name;
  val id = id;
  val owner = owner;
  val mutable x:float = 0.0
  val mutable y:float = 0.0
  method get_x = x
  method get_y = y
  method get_point = (x,y)
  method moveto (a,b) = x <- a; y <- b
  method rmoveto (dx, dy) = x <- x +. dx ; y <- y +. dy
  method to_string () = "( " ^ "I am Missile " ^ (string_of_int id) ^ " and my owner is   " ^ (owner) ^ ")";
  method position () = "(" ^ (string_of_float x) ^ "," ^ (string_of_float y) ^ ")";
  method distance () = sqrt (x*.x +. y*.y)
end;;

谢谢

2 个答案:

答案 0 :(得分:2)

正如didierc所说:

“并发访问控制台输出流总是一个问题。刷新缓冲区是常见的补救措施,否则数据会保留在缓冲区中,并且可能永远不会在程序终止之前到达控制台。当多个进程或线程写入时会出现此问题同一个终端,或者当一个进程输出到多个流都连接到同一个终端时(如stdout和stderr)“

所以你应该通过添加flush_all();;在调用Thread.delay之前

(谢谢你的回答!)

答案 1 :(得分:2)

Printf.*函数被缓冲(因为我认为是格式化功能),而print_*prerr_*则没有。如果您将printf替换为print_endline,您将看到输出按预期发生,而不必使用flush缓冲区。

所以这与我最初提到的缓冲区争用或并发访问无关,而只是简单的内部(非系统)缓冲。

传递的一些评论:你不需要在方法的末尾放置分号(尽管语法接受它)。此外,^运算符之间的表达式括号是多余的。我想这两者都是风格问题。

享受OCaml!