2012-12-08 48 views
3

我正在爲一個類項目開發一個小型的反導彈模擬器。Ocaml:Thread.delay不能按我期望的那樣工作

理念是形成爲具有不同的進程/線程彼此comunicating。

我開始研究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.25s。

我在做什麼錯?我嘗試了很多不同的東西。它只是表現奇怪的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;; 

謝謝

+0

線程創建代碼位於launchMissile函數的帖子上。這是編譯命令: ocamlc -o enemy -thread unix。cma threads.cma missile.cmo enemy.ml 沒有錯誤,唯一的問題是它不打印它應該是什麼。 沒有Thread.delay它打印,它不會停止。 我不再使用任何代碼。如果你需要別的東西告訴我! 它真的讓我瘋狂 –

+1

只是一個巫術猜測:add flush_all();在調用Thread.delay之前。 – rgrinberg

+0

那麼工作!你想添加一個答案來解釋它嗎?爲什麼會這樣工作?無論如何謝謝!我真的很好奇 –

回答

2

Printf.*功能緩衝(因爲格式設置功能,我想),而print_*prerr_*都沒有。如果您將printf替換爲print_endline,您將看到輸出按預期發生,而無需flush緩衝區。

所以這也無關緩衝爭或併發訪問,因爲我原來說的,但只是普通的內部(非系統)的緩衝。

在傳遞一個幾句話:你不需要把分號在方法結束(雖然語法接受它)。此外,表達式周圍的括號在運營商之間是多餘的。這兩個都是我猜想的風格問題。

享受OCaml!

2

如回答didierc:

「併發訪問控制檯輸出流總是存在一個問題,刷新緩衝區是通常的補救措施,否則數據將停留在緩衝區中,並且在程序終止前可能永遠不會到達控制檯。當多個進程或線程寫入同一個終端或者當一個進程過程輸出到幾流都連接到同一個終端(如輸出和錯誤)」

所以,你應該加入flush_all()做到​​這一點;;調用Thread.delay

之前(謝謝你的回答!)

相關問題