understanding fork() - Unix

This is a discussion on understanding fork() - Unix ; > On Fri, 30 May 2008 03:30:20 +0500, arnuld wrote: > I am not able to find a match between his explanation of the way > fork() works and the code he used to explain the fork(). This is the ...

+ Reply to Thread
Results 1 to 4 of 4

Thread: understanding fork()

  1. Re: understanding fork()

    > On Fri, 30 May 2008 03:30:20 +0500, arnuld wrote:


    > I am not able to find a match between his explanation of the way
    > fork() works and the code he used to explain the fork(). This is the code
    > from section 4.8 titled "Concurrent Servers":


    Ah... no, it is the code from section 5.3, not 4.8 though for-loop is the
    same.



    --
    http://lispmachine.wordpress.com/
    my email ID is @ the above blog.


  2. Re: understanding fork()

    >WHAT I KNOW:
    >
    > I can understand fork() using diagrams shown in Stevens'
    > UnP volume 1 and I do know that it copies the parent process
    > with all the data and then it just works like another server.
    >
    >
    >PROBLEM:
    >
    >I am not able to find a match between his explanation of the way
    >fork() works and the code he used to explain the fork(). This is the code
    >from section 4.8 titled "Concurrent Servers":
    >
    >
    >#include "unp.h"
    >
    >int main(int argc, char **argv)
    >{
    > int listenfd, connfd;
    > pid_t childpid;
    > socklen_t clilen;
    > struct sockaddr_in cliaddr, servaddr;
    >
    > listenfd = Socket(AF_INET, SOCK_STREAM, 0);
    >
    > bzero(&servaddr, sizeof(servaddr));
    > servaddr.sin_family = AF_INET;
    > servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    > servaddr.sin_port = htons(SERV_PORT);
    >
    > Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
    >
    > Listen(listenfd, LISTENQ);
    >
    > for ( ; ; ) {
    > clilen = sizeof(cliaddr);
    > connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);
    >
    > if ( (childpid = Fork()) == 0) { /* child process */
    > Close(listenfd); /* close listening socket */
    > str_echo(connfd); /* process the request */
    > exit(0);
    > }
    > Close(connfd); /* parent closes connected socket */
    > }
    >}
    >
    >
    >
    >1.) After listen() we get an infinite loop.


    Daemons don't usually terminate unless told to or by system shutdown.

    >2.) In the infinite-loop we accept() the connection and the hence the
    > socket can be converted back to listen() only when we do close(connfd)
    > which is not going to happen till we get out of the infinite loop.
    > Till we are in this infinite loop server will not listen to anything
    > because we have accept()ed the connection.


    listen() once, accept repeatedly. I see no way to undo a listen(),
    other than close(). That means a busy mail server can end up doing
    a listen() on a socket once a month (after it comes up from
    maintenance) and then do 300 million accept()s of connections with
    incoming spam without having to do another listen(). The only
    reason to repeat a listen() call on the same socket is to change
    the backlog.

    >3.) If we fork() then we get an if-loop after accept(). The only way to


    The if statement is not a loop. What loop? You mean one inside str_echo(),
    which wasn't in your post?

    > get out of this loop is to close/exit the child process. Hence we need


    This happens as soon as str_echo() returns. Does that keep echoing
    input until the program connecting closes the socket on their end?

    > to kill the current child process to get a new fork().


    The parent process does not wait for the child to finish. You can
    have a large number of children going at the same time. In the
    case of mail servers, you really have to deal with the possibility
    that new processes are being created so fast you're going to run
    out of resources to handle them, and fork() is going to fail.

    Go read the manual page for fork().
    How many times does a fork() call return for each call? Hint: 2.
    What return value does fork() return *IN THE PARENT PROCESS*?
    What return value does fork() return *IN THE CHILD PROCESS*?
    What does that if statement do *IN THE PARENT PROCESS*?
    What does that if statement do *IN THE CHILD PROCESS*?

    >4.) after fork() is killed, we close(connfd) and hence we get back to the
    > listen() socket and server starts to listen() again.


    The child process should not normally be killed - it does its thing
    and exit()s. The child never reaches the close(Connfd).

    >from 2,3 and 4, I can conclude

    a lot of incorrect stuff.

    >but theoretically, concurrent server handles many clients at single point
    >of time by repeatedly calling fork. I am confused on this, code does not
    >explain this. any help ?



  3. Re: understanding fork()

    > On Thu, 29 May 2008 02:52:21 -0500, Gordon Burditt wrote:

    > listen() once, accept repeatedly. I see no way to undo a listen(),
    > other than close(). That means a busy mail server can end up doing
    > a listen() on a socket once a month (after it comes up from
    > maintenance) and then do 300 million accept()s of connections with
    > incoming spam without having to do another listen(). The only
    > reason to repeat a listen() call on the same socket is to change
    > the backlog.


    > .... SNIP...


    okay, I understood it now and have even written a program that handles
    severs client using fork and server echoes back what client says. I will
    put it in a separate thread to have some views.

    Thanks


    --
    http://lispmachine.wordpress.com/
    my email ID is @ the above blog.


  4. understanding fork()

    WHAT I KNOW:

    I can understand fork() using diagrams shown in Stevens'
    UnP volume 1 and I do know that it copies the parent process
    with all the data and then it just works like another server.


    PROBLEM:

    I am not able to find a match between his explanation of the way
    fork() works and the code he used to explain the fork(). This is the code
    from section 4.8 titled "Concurrent Servers":


    #include "unp.h"

    int main(int argc, char **argv)
    {
    int listenfd, connfd;
    pid_t childpid;
    socklen_t clilen;
    struct sockaddr_in cliaddr, servaddr;

    listenfd = Socket(AF_INET, SOCK_STREAM, 0);

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(SERV_PORT);

    Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));

    Listen(listenfd, LISTENQ);

    for ( ; ; ) {
    clilen = sizeof(cliaddr);
    connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);

    if ( (childpid = Fork()) == 0) { /* child process */
    Close(listenfd); /* close listening socket */
    str_echo(connfd); /* process the request */
    exit(0);
    }
    Close(connfd); /* parent closes connected socket */
    }
    }



    1.) After listen() we get an infinite loop.

    2.) In the infinite-loop we accept() the connection and the hence the
    socket can be converted back to listen() only when we do close(connfd)
    which is not going to happen till we get out of the infinite loop.
    Till we are in this infinite loop server will not listen to anything
    because we have accept()ed the connection.

    3.) If we fork() then we get an if-loop after accept(). The only way to
    get out of this loop is to close/exit the child process. Hence we need
    to kill the current child process to get a new fork().

    4.) after fork() is killed, we close(connfd) and hence we get back to the
    listen() socket and server starts to listen() again.


    from 2,3 and 4, I can conclude that server is going to handle only one
    child at a time and if he wants to create another child, he has to get out
    of if-loop which he can do only by killing the current child process. so
    it is like an iterative server, only one fork() at one time because you
    are stuck inside the if-loop till its current fork() gets killed.

    but theoretically, concurrent server handles many clients at single point
    of time by repeatedly calling fork. I am confused on this, code does not
    explain this. any help ?



    --
    http://lispmachine.wordpress.com/
    my email ID is @ the above blog.


+ Reply to Thread