Loading ...
Sorry, an error occurred while loading the content.
 

Re: "ocaml_beginners"::[] managing multiple pipes and forks

Expand Messages
  • Richard Jones
    ... Have you tried looking at using threads and the Event module? If you grab the Adwords Toolkit from http://merjis.com/developers/adwords_toolkit and look
    Message 1 of 3 , Oct 1, 2006
      On Sat, Sep 30, 2006 at 07:22:46PM -0000, jshaw10 wrote:
      > I've been reading the online ocaml book and I have some interest in
      > parallel programming sections. My goal is to learn to use fork and
      > sockets to make multiple parallel threads, and perhaps do something
      > with server/client networking. For now I'm just trying to learn how to
      > handle multiple client threads in parallel with a server thread, with
      > 2-way communication between each.

      Have you tried looking at using threads and the Event module? If you
      grab the Adwords Toolkit from
      http://merjis.com/developers/adwords_toolkit and look at the file
      adwords_mt.ml you'll see an example of worker threads being created,
      controlled by a single thread which sends out commands using the Event
      module.

      Rich.

      --
      Richard Jones, CTO Merjis Ltd.
      Merjis - web marketing and technology - http://merjis.com
      Internet Marketing and AdWords courses - http://merjis.com/courses - NEW!
      Merjis blog - http://blog.merjis.com - NEW!
    • jshaw10
      Sorry I couldnt get back here earlier - it takes so long for posts to appear. Anyway, I fixed it to work. Here s the working vesion: type pipes = {server_read
      Message 2 of 3 , Oct 1, 2006
        Sorry I couldnt get back here earlier - it takes so long for posts to
        appear. Anyway, I fixed it to work. Here's the working vesion:

        type pipes =
        {server_read : Unix.file_descr;
        server_write : Unix.file_descr;
        client_read : Unix.file_descr;
        client_write : Unix.file_descr}

        type pipe_tracking = Chan of pipes | Null

        let test () =
        let threadnum = 2 in
        let client_thread_aux (label,inpipe,outpipe) =
        while true do
        Thread.delay (0.1);
        let insize = (Unix.fstat inpipe).Unix.st_size in
        let str = String.make insize ' ' in
        ignore (Unix.read inpipe str 0 insize);
        if str="q" then (
        ignore(Unix.write outpipe "quit" 0 4);
        exit 0;
        )
        done
        in
        let client_thread = Unix.handle_unix_error client_thread_aux in
        let server_thread_aux () =
        let pipes = Array.create threadnum Null in
        let rec makepipes = function
        0 -> ()
        | n when n>0 ->
        let (read,write) = Unix.pipe () in
        let (read2,write2) = Unix.pipe () in
        pipes.(n-1) <- Chan {server_read = read;
        server_write = write;
        client_read = read2;
        client_write = write2};
        makepipes (n-1)
        | _ -> () in
        makepipes threadnum;
        let rec quit_threads = function
        0 -> (
        match pipes.(0) with
        Null -> ()
        | Chan x ->
        ignore (Unix.write x.client_write "q" 0 1);
        )
        | n when n>0 -> (
        match pipes.(n) with
        Null -> quit_threads (n-1)
        | Chan x ->
        ignore (Unix.write x.client_write "q" 0 1);
        quit_threads (n-1)
        )
        | _ -> () in
        let rec make_threads = function
        -1 ->
        let threads_remaining = ref threadnum in
        while !threads_remaining>0 do
        for i=0 to threadnum-1 do
        match pipes.(i) with
        Null -> ()
        | Chan x ->
        let insize = (Unix.fstat x.server_read).Unix.st_size in
        let str = String.make insize ' ' in
        ignore (Unix.read x.server_read str 0 insize);
        if str="quit" then (
        print_string "received \"quit\" from ";
        print_endline (string_of_int i);
        pipes.(i) <- Null;
        threads_remaining := !threads_remaining-1;
        )
        else (
        print_string "text to send to the thread ";
        print_string (string_of_int i);
        print_string ": ";
        let outstr = read_line () in
        match outstr with
        "q" -> ignore (Unix.write x.client_write outstr 0 1);
        | "quit" ->
        quit_threads (threadnum-1);
        exit 0;
        | _ -> ()
        )
        done;
        done;
        exit 0
        | n when n>(-1) ->
        (
        match pipes.(n) with
        Null -> ()
        | Chan x ->
        match Unix.fork () with
        0 -> client_thread (n,x.client_read,x.server_write)
        | id -> make_threads (n-1)
        )
        | _ -> ()
        in make_threads (threadnum-1) in
        let server_thread = Unix.handle_unix_error server_thread_aux in
        server_thread ();;

        test ()
      Your message has been successfully submitted and would be delivered to recipients shortly.