10 childs and a socket

Started by
5 comments, last by NuffSaid 21 years, 4 months ago
Didn''t know how else to phrase my question, hence the weird subject . Anyway, I''m currently writing a program that acts like a server. It should accept a connection on a port specified by a user, and print a message to the client. Now, this works fine if there aren''t any children. But when I''ve got the children (10 of them), it doesn''t work anymore. Below is how I''m trying to spawn the 10 children. cfg.num_child == 10. What the code is trying to do, is to loop 10 times. In each iteration, it forks and if it is the child process, it breaks out of the loop. If the approach is right, the parent will be looping 10 times, forking off a child at each point.
  
for(i = 0; i < cfg.num_child; i++) {
    if(fork() == 0) {
      printf("This is the child. pid = %d\n", getpid());
      setgid(CHILD_GID);
      break;
    }
}  
If I uncomment out that chunk of code, everything works fine. However, if its in, no connections are accepted. Also, it might be of importance, but I''ve already set up the socket, bound it, and called listen before I''m forking all these children. Can someone tell me what''s wrong? Thanks
==========================================In a team, you either lead, follow or GET OUT OF THE WAY.
Advertisement
Ok, better yet, how do I prefork? I''ve seen this technique mentioned, but I haven''t seen much detail about it.

Anyone able to fill me in?
==========================================In a team, you either lead, follow or GET OUT OF THE WAY.
Normally, I''d answer the question, but i don''t have the time at the moment to go take a peek at a simple dameon like in.identd to see what to do

so i''ll just suggest that you do.
The problem you might be having is this.

each time you fork the child process gets copy of all open file descriptors, which on a unix box is files and sockets.

so after you parent loop through you have 11 processes each on with the accept code on the same socket/port.

There I think is your problem. You should only have one process
that is listening for accepts.

why are you forking childern off a process that is doing accepts (which i guess is also creating the sockets after accepts).

what most server do is create a new thread for each accept with each thread have a socket connection.

Lord Bart
Just thought I''d expand on Lord Bart''s post.

Yes, the problem is almost certainly the fact that forked processes retain the same open file-descriptors (e.g. sockets) as their parents.
Your code is essentially forking at about the time you would fork of processes if you were pre-forking, except you''re not doing it right (more on that later).
The typical forking server would look something like this (pseudo-code):

  int acceptsocket = socket();bind ( acceptsocket );listen ( acceptsocket );while ( 1 ) {    int newsock = accept ( acceptsocket );    if ( fork() == 0 ) {        // We''re the child. Close acceptsocket.        close ( acceptsocket );        handle_client ( newsock );        exit(0);    }    // We''re the parent. Close newsock.    close ( newsock );    // Continue to listen for connections}  


Now, the problem with the standard forking servers like that is that forking is fairly expensive, so if the client/server interaction is short the overhead of forking can be prohibitly high compared to the work that needs to be done on the server. Enter pre-forking.
My advise, however, is *not* to get embroiled in that, as it is fairly complicated (IPC is needed to notify children when there is work to do, and to notify the parent when a child-process has completed processing. As well as handing over sockets and so on.), and in most cases a threaded server will be equally useful anyway.

So, in short, either stick with a regular forking server, or use a threaded server.

-Neophyte
Thanks for the info. For some weird reason, it works now (and I didn''t change a thing...).
==========================================In a team, you either lead, follow or GET OUT OF THE WAY.
To the people above who thought you couldn''t have the same file descriptors...

you can. each process is waken up out of the sleep and the first one to get scheduled gets the connection, the rest just find nothing and (usually) go to sleep again.

- C-Junkie (too lazy to enter password...)

This topic is closed to new replies.

Advertisement