caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Client/Server socket communication
@ 2002-09-18  2:51 IKEDA Katsumi
  2002-09-18  3:07 ` Tim Freeman
  0 siblings, 1 reply; 6+ messages in thread
From: IKEDA Katsumi @ 2002-09-18  2:51 UTC (permalink / raw)
  To: caml-list

Hi,

I use Ocaml 3.06 on Vine Linux 2.1.5.
Vine Linux is RedHat 5.* and 6.* based distribution and ...
  kernel: 2.2.18
  libc:   6 -> 2.1.3

I make Client/Server socket communication program.

The followings are the lists.

---------------- server.ml ----------------
(* server.ml *)

let openSock port = 
  let sock = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in
  begin
    Unix.bind sock (Unix.ADDR_INET(Unix.inet_addr_any,port));
    Unix.listen sock 20;
    sock
  end
;;

let waitChild s = 
  print_string "server: waitChild called\n";
  flush stdout ;
  let s =  Unix.waitpid [ Unix.WNOHANG ] 0 in ()
;;

let main() =
  Sys.set_signal Sys.sigchld (Sys.Signal_handle waitChild) ;
  print_string "server started.\n";
  flush stdout;
  let port = 999999 in
  let sock = openSock port in
  begin
    while true do
      try
        let (fd,a) = Unix.accept sock in 
        begin
          print_string "server accepted \n"; 
          flush stdout;
          let pid = Unix.fork() in
          match pid with
            0  ->
	      begin
		print_string "run a child process.\n";
		flush stdout;
		let buf = String.create 10 in
		let ret = Unix.read fd buf 0 10 in
		begin
		  print_string "ret = "; print_int ret; print_newline();
		  print_string buf; print_newline();
		  flush stdout;
		  Unix.sleep(3);
		  print_string "exit a child process.\n";
		  flush stdout;
		  exit 0
		end
              end
	  | _ -> (* parent process *)
              begin
		print_string "server parent side\n";
		flush stdout ;
              end
	end
      with
	Unix.Unix_error(err, ctx1, ctx2) ->
	  if (err = Unix.EINTR) then
	    print_string "Function interrupted by signal\n"
 	  else
	    begin
	      print_string "Unix.Unix_error in main\n";
	    end
      | _ -> print_string "Unexpected Exception\n"
    done;
  end
;;

main();;
--------------------------------

---------------- client.ml ----------------
let main() =
  let server_address =  "127.0.0.1" and port = 999999 in
  let sock = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in
  Unix.connect sock(Unix.ADDR_INET((Unix.inet_addr_of_string server_address),
				   port));
  let msg = "Hello!" in
  let ret = Unix.write sock msg 0 (String.length msg) in
  print_string "reg = "; print_int ret; print_newline();
  flush stdout;
  Unix.close sock;
;;

main();;
----------------

I compiled these by ocamlc.

Now, I make run_client.sh script

---------------- run_client.sh ----------------
#!/bin/sh
./client &
./client &
./client &
./client &
./client &
./client &
./client &
./client &
./client &
./client &
--------------------------------

I run "./server &".
Then I run "./run_client.sh" several times.

I found something wrong.
I run "ps" command, it displays the following:

  PID TTY          TIME CMD
 1225 pts/3    00:00:00 sh
 3156 pts/3    00:00:00 server
 3197 pts/3    00:00:00 server <defunct>
 3226 pts/3    00:00:00 ps

Why "server <defunct>" is occurred.
What do I have to do to correct <defunct> ?

thanks.

-- 
IKEDA Katsumi  <ikeda@msi.co.jp>
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Caml-list] Client/Server socket communication
  2002-09-18  2:51 [Caml-list] Client/Server socket communication IKEDA Katsumi
@ 2002-09-18  3:07 ` Tim Freeman
  2002-09-18  4:04   ` IKEDA Katsumi
  2002-09-18  8:23   ` Alessandro Baretta
  0 siblings, 2 replies; 6+ messages in thread
From: Tim Freeman @ 2002-09-18  3:07 UTC (permalink / raw)
  To: ikeda; +Cc: caml-list

>Why "server <defunct>" is occurred.
>What do I have to do to correct <defunct> ?

This is a Unix thing, not an OCAML thing.  The child will be defunct
to hold the exit status so it can be reported to the parent when the
parent waits for it, or until the parent exits.

One workaround is to wait for the child process when you expect it to exit.

Another workaround is to fork twice, so the original process is the
parent of a temporary process, and the temporary process is the parent
of the process you really wanted to create.  The temporary process
exits immediately and the original parent waits for it immediately.
This leaves no defunct processes.

-- 
Tim Freeman       
tim@fungible.com
GPG public key fingerprint ECDF 46F8 3B80 BB9E 575D  7180 76DF FE00 34B1 5C78 
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Caml-list] Client/Server socket communication
  2002-09-18  3:07 ` Tim Freeman
@ 2002-09-18  4:04   ` IKEDA Katsumi
  2002-09-18 19:27     ` Tim Freeman
  2002-09-18  8:23   ` Alessandro Baretta
  1 sibling, 1 reply; 6+ messages in thread
From: IKEDA Katsumi @ 2002-09-18  4:04 UTC (permalink / raw)
  To: caml-list

Hi,
Thank you for your quick reply.

From: tim@fungible.com (Tim Freeman)
Message-ID: <20020918031351.4EC427F4F@lobus.fungible.com>
> Another workaround is to fork twice, so the original process is the
> parent of a temporary process, and the temporary process is the parent
> of the process you really wanted to create.  The temporary process
> exits immediately and the original parent waits for it immediately.
> This leaves no defunct processes.

I try this solution.
But <defunct> is occurred.
Do I misunderstand your advice?

Modified server.ml is the following.

---------------- server.ml ----------------
(* server.ml *)

let openSock port = 
  let sock = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in
  begin
    Unix.bind sock (Unix.ADDR_INET(Unix.inet_addr_any,port));
    Unix.listen sock 20;
    sock
  end
;;

let waitChild s = 
  print_string "server: waitChild called\n";
  flush stdout ;
  let s =  Unix.waitpid [ Unix.WNOHANG ] 0 in ()
;;

let run_child fd =
  let pid2 = Unix.fork() in
  match pid2 with
    0 ->
      begin
	print_string "run a child process.\n";
	flush stdout;
	let buf = String.create 10 in
	let ret = Unix.read fd buf 0 10 in
	begin
	  print_string "ret = "; print_int ret; print_newline();
	  print_string buf; print_newline();
	  flush stdout;
	  Unix.sleep(5);
	  print_string "exit a child process.\n";
	  flush stdout;
	  exit 0
	end
      end
  | _ ->
      begin
	print_string "exit temporary parent.\n";
	flush stdout;
	exit 0
      end
;;
	

let main() =
  Sys.set_signal Sys.sigchld (Sys.Signal_handle waitChild) ;
  print_string "server started.\n";
  flush stdout;
  let port = 999999 in
  let sock = openSock port in
  while true do
    try
      let (fd,a) = Unix.accept sock in 
      begin
        print_string "server accepted \n"; 
        flush stdout;
        let pid = Unix.fork() in
        match pid with
          0  ->
	    run_child fd
	| _ -> (* parent process *)
	    begin
	      print_string "server parent side\n";
	      flush stdout ;
	    end
      end
    with
      Unix.Unix_error(err, ctx1, ctx2) ->
	if (err = Unix.EINTR) then
	  print_string "Function interrupted by signal\n"
 	else
	  begin
	    print_string "Unix.Unix_error in main\n";
	  end
    | _ -> print_string "Unexpected Exception\n"
  done;
;;

main();;
--------------------------------

thanks.

-- 
IKEDA Katsumi  <ikeda@msi.co.jp>
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Caml-list] Client/Server socket communication
  2002-09-18  3:07 ` Tim Freeman
  2002-09-18  4:04   ` IKEDA Katsumi
@ 2002-09-18  8:23   ` Alessandro Baretta
  1 sibling, 0 replies; 6+ messages in thread
From: Alessandro Baretta @ 2002-09-18  8:23 UTC (permalink / raw)
  To: Ocaml



Tim Freeman wrote:
>>Why "server <defunct>" is occurred.
>>What do I have to do to correct <defunct> ?
> 
> 
> This is a Unix thing, not an OCAML thing.  The child will be defunct
> to hold the exit status so it can be reported to the parent when the
> parent waits for it, or until the parent exits.
> 
> One workaround is to wait for the child process when you expect it to exit.
> 
> Another workaround is to fork twice, so the original process is the
> parent of a temporary process, and the temporary process is the parent
> of the process you really wanted to create.  The temporary process
> exits immediately and the original parent waits for it immediately.
> This leaves no defunct processes.
> 

A third workaround might be to use SIGCHLD handler to 
asynchronously call wait or waitpid, but there might be 
issues with the non-reentrance-with-respect-to-signals of 
the libc. I doubt O'Caml could be any more signal-safe than 
libc.

A fourth workaround is to use O'Caml threads, which do not 
require the kernel to instantiate a new process, so no new 
pid is allocated.

Alex

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Caml-list] Client/Server socket communication
  2002-09-18  4:04   ` IKEDA Katsumi
@ 2002-09-18 19:27     ` Tim Freeman
  2002-09-19  1:52       ` IKEDA Katsumi
  0 siblings, 1 reply; 6+ messages in thread
From: Tim Freeman @ 2002-09-18 19:27 UTC (permalink / raw)
  To: ikeda; +Cc: caml-list


>I try this solution.
>But <defunct> is occurred.
>Do I misunderstand your advice?

At the place you printed "server parent side", you should have saved
the pid that came back from fork and done a wait on it.  The call to
wait should be something like

   Unix.waitpid [] pid

where pid is the process id that came back from forking the temporary parent.

-- 
Tim Freeman       
tim@fungible.com
GPG public key fingerprint ECDF 46F8 3B80 BB9E 575D  7180 76DF FE00 34B1 5C78 
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Caml-list] Client/Server socket communication
  2002-09-18 19:27     ` Tim Freeman
@ 2002-09-19  1:52       ` IKEDA Katsumi
  0 siblings, 0 replies; 6+ messages in thread
From: IKEDA Katsumi @ 2002-09-19  1:52 UTC (permalink / raw)
  To: caml-list

Hi,

From: tim@fungible.com (Tim Freeman)
Message-ID: <20020918192934.92D177F65@lobus.fungible.com>
> 
> >I try this solution.
> >But <defunct> is occurred.
> >Do I misunderstand your advice?
> 
> At the place you printed "server parent side", you should have saved
> the pid that came back from fork and done a wait on it.  The call to
> wait should be something like
> 
>    Unix.waitpid [] pid
> 
> where pid is the process id that came back from forking the temporary parent.

Mr. John also teach me same solution.

Now, my program works well.

Thanks.

-- 
IKEDA Katsumi  <ikeda@msi.co.jp>
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2002-09-19  1:52 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-09-18  2:51 [Caml-list] Client/Server socket communication IKEDA Katsumi
2002-09-18  3:07 ` Tim Freeman
2002-09-18  4:04   ` IKEDA Katsumi
2002-09-18 19:27     ` Tim Freeman
2002-09-19  1:52       ` IKEDA Katsumi
2002-09-18  8:23   ` Alessandro Baretta

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).