Archived

This topic is now archived and is closed to further replies.

10 childs and a socket

This topic is 5498 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
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...)

Share this post


Link to post
Share on other sites