From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by yquem.inria.fr (Postfix) with ESMTP id 94FB6BBAF for ; Fri, 16 Jul 2010 15:03:11 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AuMBAJ71P0zZSMDqkWdsb2JhbACfaRUBAQEBCQsKBxEDH74/hSQE X-IronPort-AV: E=Sophos;i="4.55,214,1278280800"; d="scan'208";a="54339612" Received: from fmmailgate03.web.de ([217.72.192.234]) by mail3-smtp-sop.national.inria.fr with ESMTP; 16 Jul 2010 15:02:50 +0200 Received: from smtp02.web.de ( [172.20.0.184]) by fmmailgate03.web.de (Postfix) with ESMTP id 5742E15BA2CD6; Fri, 16 Jul 2010 15:02:49 +0200 (CEST) Received: from [78.43.204.177] (helo=frosties.localdomain) by smtp02.web.de with asmtp (TLSv1:AES256-SHA:256) (WEB.DE 4.110 #4) id 1OZkYz-0003EA-00; Fri, 16 Jul 2010 15:02:49 +0200 Received: from mrvn by frosties.localdomain with local (Exim 4.72) (envelope-from ) id 1OZkYy-0003Hz-A2; Fri, 16 Jul 2010 15:02:48 +0200 From: Goswin von Brederlow To: Rich Neswold Cc: Goswin von Brederlow , caml-list@yquem.inria.fr Subject: Re: [Caml-list] Smart ways to implement worker threads References: <87sk3mcaeq.fsf@frosties.localdomain> <87zkxsfvsg.fsf@frosties.localdomain> <87hbk0vzut.fsf@frosties.localdomain> Date: Fri, 16 Jul 2010 15:02:48 +0200 In-Reply-To: (Rich Neswold's message of "Thu, 15 Jul 2010 23:23:19 -0500") Message-ID: <87630fbmvb.fsf@frosties.localdomain> User-Agent: Gnus/5.110009 (No Gnus v0.9) XEmacs/21.4.22 (linux, no MULE) MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit Sender: goswin-v-b@web.de X-Sender: goswin-v-b@web.de X-Provags-ID: V01U2FsdGVkX1/pZHCYS5xJOJ57AV2+nPNfMyU4Cqa0WtL0qiF0 3IlGexIK043EXtIyzj0TUtCYdgnB//gJtnwHot5/hpHS4gAryg zFs/0HHoo= X-Spam: no; 0.00; printf:01 printf:01 ocamlopt:01 -thread:01 foo:01 cmxa:01 cmxa:01 foo:01 reppy:01 val:01 val:01 recieved:98 recieved:98 mfg:98 threads:01 Rich Neswold writes: > On Thu, Jul 15, 2010 at 11:02 PM, Goswin von Brederlow > wrote: > > Rich Neswold writes: > > Thanks. That is about what I got so I do seem to understand the > differences right. > > For my use case this would then come down to implement solution 3 with > channels instead of my own queues. Well, channels are thread safe queues > just by another name. I think I see now how they make the code simpler > to write. > > > Channels are a thread-safe communication channel of depth one (i.e. you can > only pass one item at a time.) The channel is a primitive that allows reliable Urgs, so what happens if I call "sync (send ...)" twice without the other end calling recieve? Lets test: let ch = Event.new_channel () let reciever () = for i = 0 to 10 do Printf.printf "recieved %d\n" (Event.sync (Event.receive ch)); flush_all (); Unix.sleep 2; done let _ = ignore (Thread.create reciever ()); for i = 0 to 10 do Printf.printf "sending %d\n" i; flush_all (); Event.sync (Event.send ch i); Unix.sleep 1; done % ocamlopt -thread -o foo unix.cmxa threads.cmxa foo.ml && ./foo sending 0 recieved 0 sending 1 recieved 1 sending 2 recieved 2 sending 3 recieved 3 ... So the send blocks until the event is recieved. That certainly isn't helpfull for me. One could say I want asynchronous remote function calls (and returns). > synchronized communication between threads. The Reppy book describes in later > chapters how to use the channel primitive to build up queues and other, more > complicated constructs (like RPCs and multicasting to many processes.) > > In fact, you might use the RPC ideas to pass your checksumming requests to > worker tasks and receive the results. Yeah. But then why not build it around the simple Mutex and Condition modules instead of Event? At first glance the blocking aspect of Events seem to be more of a hindrance than help. I find it odd that there is no Threaded_Queue module, a thread save version of Queue with 2 extra functions: val wait_and_take : 'a t -> 'a wait_and_take q waits for the queue q to be not empty and removes and returns the first element in queue q. Raises Empty when the queue is closed. val close : 'a t -> unit close q closes the queue and wakes up waiting threads. MfG Goswin