
161cf51508e34bdcf00fecec81f877f6.ppt
- Количество слайдов: 24
Concurrent Servers
Idea Behind Concurrent Servers Server X Server 1 Client 1
Idea Behind Concurrent Servers Server 1 Client 1
Idea Behind Concurrent Servers Server 1 Client 2
Idea Behind Concurrent Servers Server 1 Client 1 Server 2 Client 2
Idea Behind Concurrent Servers Server 1 Client 1 Server 2 Client 2
Idea Behind Concurrent Servers Server X Server 1 Client 1 Server 2 Client 2
Idea Behind Concurrent Servers Server 1 Client 1 Server 2 Client 2
Creating a New Server - fork() listenfd = Socket( … ) Initialize server address Bind( listenfd, … ) for ( ; ; ) { /* wait for client connection */ connfd = Accept(listenfd, …); if( (pid = Fork() ) = = 0) { /*I am the child */ Close(listenfd); service_client(connfd); Close(connfd); exit(0); } else /* I am the parent */ Close(connfd); }
Points to Note • fork() is called once … • …but it returns twice!! – Once in the parent server and – Once in the child server • How to distinguish parent and child? ?
Points to Note • fork() is called once … • …but it returns twice!! – Once in the parent server and – Once in the child server • How to distinguish parent and child? ? – Return value in child = 0 – Return value in parent = process id of child
Points to Note • fork() is called once … • …but it returns twice!! – Once in the parent server and – Once in the child server • How to distinguish parent and child? ? – Return value in child = 0 – Return value in parent = process id of child • Child server exits after servicing the client.
Running another program in child – exec()
Running another program in child – exec() Inetd daemon listenfd = Socket(…) Connfd = Accept(…)
Running another program in child – exec() Inetd child Inetd daemon listenfd = Socket(…) Connfd = Accept(…) Fork(…) Close(listenfd)
Running another program in child – exec() Inetd child Inetd daemon listenfd = Socket(…) Connfd = Accept(…) Fork(…) Close(listenfd) Exec(…) Telnet server Service telnet client Close(connfd)
Different Types of exec() • int execl(char * pathname, char * arg 0, … , (char *)0); • int execv(char * pathname, char * argv[]); • int execle(char * pathname, char * arg 0, … , (char *)0, char envp[]); • int execve(char * pathname, char * argv[], char envp[]); • int execlp(char * filename, char * arg 0, … , (char *)0); • int execvp(char * filename, char * argv[]);
Properties of exec() • Replaces current process image with new program image. – E. g. inetd image replaced by telnet image • All descriptors open before exec remain open after exec.
Getting IP address/port from socket • int getsockname(int sockfd, struct sockaddr *localaddr, socklen_t *addrlen) – Get the local IP/port bound to socket • int getpeername(int sockfd, struct sockaddr *remoteaddr, socklen_t *addrlen) – Get the IP/port of remote endpoint • Why do we need these?
Two other useful functions • struct hostent *gethostbyaddr (void *addr, size_t len, int type); – Converts from IP addr to domain name • struct hostent *gethostbyname (char *name); – Converts from domain name to IP address • } struct hostent { char *h_name; /* official name of host */ char **h_aliases; /* alias list */ int h_addrtype; /* address type */ int h_length; /* address length*/ char **h_addr_list; /* address list */
Signals • Signal is a notification to process (from OS or from another process) that an event has occurred. • Type of event determined by type of signal • Try listing all signal types using % kill –l • Some interesting signals – SIGCHLD, SIGTERM, SIGKILL, SIGSTOP
Handling Signals • Signals can be caught – i. e. an action associated with them – SIGKILL and SIGSTOP cannot be caught. • Actions can be customized using sigaction(…) which associates a signal handler with the signal. Details in page 120 of Steven’s book • Default action for most signals is to terminate the process – SIGCHLD and SIGURG are ignored by default. • Unwanted signals can be ignored – except SIGKILL or SIGSTOP
Zombie Processes • When a child server dies, a SIGCHLD is sent to the parent server. • If parent doesn’t wait()on the child, child becomes a zombie (status “Z” seen with ps). • Zombies hang around forever.
How to avoid zombies? • Parent should install a signal handler for SIGCHLD • Call wait(…)/waitpid(…)inside the signal handler void handle_sigchld(int signo) { pid_t pid; int stat; pid = wait(&stat); printf(“child %d terminatedn”, pid); }
161cf51508e34bdcf00fecec81f877f6.ppt