यदि आप सिमुलेशन का प्रयास करने जा रहे हैं, तो आपको केवल थ्रेड का उपयोग करने से अपने नोड्स पर बहुत अधिक नियंत्रण की आवश्यकता होगी — या कम से कम, बिना किसी मुख्य दर्द के।
सिमुलेशन पर पूर्ण नियंत्रण रखने के लिए विषय के लिए मेरा व्यक्तिपरक दृष्टिकोण एक सरल, सिंगल-थ्रेडेड वर्चुअल मशीन बनाना होगा। OCaml में ऐसा करने का सबसे आसान तरीका है (जैसा कि LWT में किया जाता है, उदाहरण के लिए) एक इकाई की तरह संरचना का उपयोग करना है:
(* A thread is a piece of code that can be executed to perform some
side-effects and fork zero, one or more threads before returning.
Some threads may block when waiting for an event to happen. *)
type thread = < run : thread list ; block : bool >
(* References can be used as communication channels out-of-the box (simply
read and write values ot them). To implement a blocking communication
pattern, use these two primitives: *)
let write r x next = object (self)
method block = !r <> None
method run = if self # block then [self]
else r := Some x ; [next()]
end
let read r next = object (self)
method block = !r = None
method run = match r with
| None -> [self]
| Some x -> r := None ; [next x]
end
आप इस तरह के एक "समय जोड़ने के रूप में बेहतर पुरातन आपकी आवश्यकताओं के अनुरूप है कि, बना सकते हैं आपके चैनलों में संपत्ति "प्रेषण के लिए आवश्यक है।
अगला चरण सिमुलेशन इंजन को परिभाषित कर रहा है।
(* The simulation engine can be implemented as a simple queue. It starts
with a pre-defined set of threads and returns when no threads are left,
or when all threads are blocking. *)
let simulate threads =
let q = Queue.create() in
let() = List.iter (fun t -> Queue.push t q) threads in
let rec loop blocking =
if Queue.is_empty q then `AllThreadsTerminated else
if Queue.length q = blocking then `AllThreadsBlocked else
let thread = Queue.pop q in
if thread # block then (
Queue.push thread q ;
loop (blocking + 1)
) else (
List.iter (fun t -> Queue.push t q) (thread # run) ;
loop 0
)
in
loop 0
फिर से, आप क्या नोड जो धागा निष्पादित हो रहा है, क्रम में प्रति नोड प्राथमिकताओं रखने के लिए ट्रैक रखने के लिए इंजन को समायोजित कर सकते एक नोड बड़े पैमाने पर धीमी या दूसरों की तुलना में तेजी से किया जा रहा है, या बेतरतीब ढंग से एक धागा उठा अनुकरण करने के लिए हर कदम पर निष्पादन के लिए, और इसी तरह।
अंतिम चरण अनुकरण को क्रियान्वित कर रहा है। यहां, मैं दो धागे यादृच्छिक संख्याओं को पीछे और पीछे भेज रहा हूं।
let rec thread name input output =
write output (Random.int 1024) (fun() ->
read input (fun value ->
Printf.printf "%s : %d" name value ;
print_newline() ;
thread name input output
))
let a = ref None and b = ref None
let _ = simulate [ thread "A -> B" a b ; thread "B -> A" b a ]
यह एक शानदार जवाब है, बहुत प्रेरक है। – Tiemen