14 3 3 實現輔助函式

2021-06-02 11:04:59 字數 2148 閱讀 5934

14.3.3 實現輔助函式

在討論計算動物位置的**之前,我們要稍稍離題。我們需要實現幾個函式,將由確定動物和捕食者位置的演算法使用。出於各種用途,這些函式需要使用隨機數,要正確地生成隨機數,首先需要討論如何安全地訪問,那些不是執行緒安全(thread-safe)的物件。這可能是個問題,當我們處理具有可變狀態的物件時,這是 .net 型別的通常情況。

安全地訪問共享物件

random 類常用的 .net 類,它不是執行緒安全的。在我們的應用程式中,需要生成隨機位置,以選擇動物或捕食者應將移動到的位置。這個函式可以同時從多個執行緒中呼叫。然而,random 需要初始化一次,然後一遍又一遍地使用。(如果你為每個呼叫建立 random 新的例項,通常會得到重複的數字,給隨機數生成器作為初始"種子"是取自系統時間。)如果你在同一例項上,從多個執行緒中呼叫 next 方法,方法的行為是未定義的。實際上,它最終開始返回零。我們負責保證,每次將只有乙個執行緒訪問乙個物件。

要避免這個問題,我們可以使用鎖,它會阻止正在執行**的其他執行緒,直到操作完成,由相同的鎖保護。這使**高效降低。清單 14.24 提供了乙個解決方案,它是安全的,但效率更高。

listing 14.24 safe way for generating random numbers (f# and c#)

f#c#

module saferandom =

let private rnd =

new random()

let new() =

lock rnd (fun () –>

new random(rnd.next())

)static class saferandom

}我們在 f# 中建立乙個模組,在 c# 中建立乙個靜態類,兩者的目的相同:可以用來生成隨機數生成器。建立兩個生成器,使用的隨機種子,來自乙個全域性隨機數生成器,在鎖內可以安全地訪問。由於這種做法,我們不必每次在需要建立乙個隨機數字時,使用鎖。我們只需要每次建立乙個新的生成器,在執行可以與其他任務並行執行的操作時。在乙個執行緒內,可以安全地重用同一例項,知道沒有其他任何執行緒會對它訪問。

f# 中與 c# 的 lock 關鍵字等效的是 lock 函式,它取乙個簡單的函式作為引數。它要求這個鎖,使用 monitor 類,執行指定的函式,然後釋放鎖。在下一節中,我們會好好利用 saferandom,在**世界中,需要在某些地點生成隨機位置。

處理位置

當生成動物的位置,我們需要生成隨機的位置,作為可能的目標;然後,我們需要某種方式,來測量哪個位置是最佳的選擇。這可能取決於和其他捕食者及動物有多近。要寫這些演算法,我們需要幾個函式。我們來看看它們的型別簽名,它應該給你足夠的資訊,來了解如何它們中如何工作的,以及我們自己如何實現。下面的**片斷顯示其注釋的 f# 型別簽名:

/// returns the distance between two specified locations

val distance : vector -> vector –> float

/// returns specified number of check-points

/// on the path between the specified locations

val getpathpoints : int * vector * vector -> seq

/// returns the specified number of randomly generated locations

val randomlocations : int -> seq

第乙個函式可以使用 math.pow 和 math.sqrt 來實現。注意,我們給這個函式幾個引數,可以使用偏應用。在 f# 中,當我們要計算從乙個特定的點,到集合中地點的距離時,是方便的。第二和第三個函式可以使用 f# 中的序列表示式和 c# 中的迭代器實現。

我們需要從並行執行的多個執行緒中呼叫 randomlocations 函式,所以,要用到先前建立的 saferandom 模組。每次呼叫 randomlocations,首先使用 saferandom.new (),建立乙個新的隨機數字生成器,然後,重複使用這個生成器去生成結果。結果是乙個延遲序列,因此,它實際是在需要時才生成。正巧,我們需要這個序列中的所有專案,來計算位置的動物,所以,這並不產生大的差異。

這三個輔助函式都是很簡單的,但我們當實現**時,一直都會用到它們。由於有了這三個函式和豐富的標準 f# 庫,運動的演算法可以用簡捷的方式來寫。

14 3 3 實現輔助函式

14.3.3 實現輔助函式 在討論計算動物位置的 之前,我們要稍稍離題。我們需要實現幾個函式,將由確定動物和捕食者位置的演算法使用。出於各種用途,這些函式需要使用隨機數,要正確地生成隨機數,首先需要討論如何安全地訪問,那些不是執行緒安全 thread safe 的物件。這可能是個問題,當我們處理具有...

13 3 1 實現 XML 輔助函式

13.3.1 實現 xml 輔助函式 linq to xml 主要用於 c 和 vb,在 f 中使用可能有些麻煩。例如,f 不支援隱式型別轉換 因為這會使型別推斷複雜 所以,每次我們指定元素名,必須使用 xname.get,而不是只使用乙個字串。或者,我們可以寫乙個簡單的工具函式或自定義運算子,來完...

STL vector 輔助函式

template inline bool operator const vector tp,alloc x,const vector tp,alloc y 判斷相等 template inline bool operator const vector tp,alloc x,const vector ...