in reply to Threads, Forks, or Nothing?

I'm writing a server that will copy data from a network interface to multiple sockets. Normally the right way to do this would be to fork a seperate process for each connection request. Unfortunately, only one process can read from the network interface at a time. If I do fork, simultaneous reads will be attempted and I'll dump core. Not a good solution.
Pardon? Why not have one reader and multiple writers; the reader and the writers speak to each other over another channel to pass the actual message forward (using message queues, sockets, shared memory, semaphores, filesystems, etc...)?

As far as fork/thread ... I'm partial to forking. But I'm a Unix snob.

Replies are listed 'Best First'.
Re: Re: Threads, Forks, or Nothing?
by rapier1 (Novice) on Aug 16, 2001 at 00:37 UTC
    One reader and multiple writers is exactly what I am trying to do. The idea with threads was to have one thread as the reader and another thread to control the writers using a shared memory space. What you suggested is essentially what I am doing now...
    in pseudo code while (1) if accept (non blocking) initialize writer add Ptr to writer hash if %writer read_cell (atm cells) foreach connection %writer if lifetime of writer exceeded undef $writer{connection} next write cell and then back through the loop.
    The problem is that initializing a writer takes a non zero amount of time. During this period we can't read any cells off the interface and at OC3 and OC12 speeds (which is what we are dealing with) it can be a significant bit of data lost. So the ideal solution would be to off load the writer initialization and handling to another thread so that existing writers wouldn't have the data flow interrupted.

    The goal is to have a server that can gracefully handle gigabit speeds and more than 5 writers at a time.

    Also, as I stated, I do not think forking can work. I can only have one reader on an interface at a time. If there is some way to only fork a subroutine I'm all ears (eyes, whatever).

      The trick there is to have your children ready before you accept. Basically you fork multiple times, then the parent sits on the socket. The moment you get a connection you just start writing to the children. In this case you would probably just have the children blocking on reads from the pipe to the parent.

      The Apache webserver does this to improve it's response times to connections. If you look at the process table while apache is running, you will see MAX_SERVERS + 1 processes. That's the parent with MAX_SERVERS children standing by.

      ____________________
      Jeremy
      I didn't believe in evil until I dated it.