Browse thread
Smart ways to implement worker threads
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
| Date: | -- (:) |
| From: | Satoshi Ogasawara <ogasawara@i...> |
| Subject: | Re: [Caml-list] Smart ways to implement worker threads |
On 2010/07/16, at 22:02, Goswin von Brederlow wrote:
> Urgs, so what happens if I call "sync (send ...)" twice without the
> other end calling recieve? Lets test:
>
> let ch = Event.new_channel ()
> ...
That's not good use of synchronous channels. If you want to asynchronous,
try Mbox module in concurrent cell.
https://forge.ocamlcore.org/scm/viewvc.php/trunk/mbox.mli?view=markup&root=ccell
open Printf
open Ccell
open Event
let mbox = Mbox.make ()
let receiver () =
for i = 0 to 10 do
printf "received %d\n%!" (sync (Mbox.pop mbox));
Thread.delay 2.;
done
let _ =
ignore (Thread.create receiver ());
for i = 0 to 10 do
printf "sending %d\n%!" i;
sync (Mbox.push mbox i);
Thread.delay 1.;
done
wednesday:tmp osiire$ ocamlc -thread unix.cma threads.cma -I +site-lib/ccell ccell.cma async.ml && ./a.out
sending 0
received 0
sending 1
received 1
sending 2
sending 3
received 2
sending 4
sending 5
received 3
sending 6
sending 7
received 4
sending 8
sending 9
received 5
sending 10
With Mbox module, you can also wait and select long calculation results like this.
open Printf
open Ccell
open Event
let rec forever f x =
let v = f x in forever f v
let spawn_loop f x =
ignore (Thread.create (forever f) x)
let make_worker f =
let input, output = Mbox.make (), Mbox.make () in
let work () =
sync (Mbox.push output (f (sync (Mbox.pop input))));
in
spawn_loop work ();
input, output
let request (input, _) p =
sync (Mbox.push input p)
let response (_, output) =
Mbox.pop output
let worker1 = make_worker (printf "action worker1 %d\n%!")
let worker2 = make_worker (printf "action worker2 %d\n%!")
let after_long_calc (e1, e2) =
select [
wrap e1 (fun _ -> printf "after work1\n%!"; (response worker1, e2));
wrap e2 (fun _ -> printf "after work2\n%!"; (e1, response worker2));
]
let _ =
spawn_loop after_long_calc (response worker1, response worker2);
request worker1 1;
Thread.delay 1.;
request worker2 2;
Thread.delay 1.;
request worker2 3;
Thread.delay 1.;
request worker1 4;
Thread.delay 2.
wednesday:tmp osiire$ ocamlc -thread unix.cma threads.cma -I +site-lib/ccell ccell.cma worker.ml && ./a.out
action worker1 1
after work1
action worker2 2
after work2
action worker2 3
after work2
action worker1 4
after work1
I hope this will be helpful for you.
---
satoshi ogasawara