TDC561 Network Programming - PowerPoint PPT Presentation

About This Presentation
Title:

TDC561 Network Programming

Description:

Default action (see manual pages man signal) is the action executed if nothing else ... Processing the signal depends also on the state of the process and level ... – PowerPoint PPT presentation

Number of Views:64
Avg rating:3.0/5.0
Slides: 34
Provided by: camelia2
Category:

less

Transcript and Presenter's Notes

Title: TDC561 Network Programming


1
TDC561 Network Programming
Week 3 Unix Asynchronous Events Signals and
Alarms API Server Concurrency Select () I/O
Multiplexing
  • Camelia Zlatea, PhD
  • Email czlatea_at_cs.depaul.edu

2
References
  • W. Richard Stevens, Network Programming
    Networking API Sockets and XTI, Volume 1, 2nd
    edition, 1998 (ISBN 0-13-490012-X)
  • Chap. 6 ( I/O Multiplexing)
  • John Shapley Gray, Interprocess Communications in
    UNIX -- The Nooks and Crannies Prentice Hall PTR,
    NJ, 1998
  • Chap. 2, 4 (signals) Chap 10.6 ( I/O
    Multiplexing )
  • Douglas Comer, David Stevens, Internetworking
    with TCP/IP Client-Server Programming, Volume
    III (BSD Unix and ANSI C), 2nd edition, 1996
    (ISBN 0-13-260969-X)
  • Chap. 3,4,5

3
Unix System Programming - Topics
  • Asynchronous Events
  • Signals Alarms

4
Asynchronous Events
  • Examples of process events
  • a signal from another process
  • an interrupt from a device
  • completion of a I/O request
  • Signals are events delivered to a process via
    UNIX. The process has no control over when they
    arrive. Signals are understood as software
    version of hardware interrupts.
  • Signals can be generated by
  • hardware ex division by zero, illegal address
    access
  • kernel ex completion of a I/O request issued by
    the waiting process
  • user processes ex communication among processes
    related to relevant events, child termination
    notified to parent
  • user actions ex pressing the keyboard sequence
    for quit, interrupt
  • To find the current mapping of the key sequences
    for various signals, call shell command stty -a
  • Example SIGINT is mapped to "ctrl c" (or DEL)

5
Unix System Calls to handle signals
  • Signal system call is used to install signal
    handlers.
  • / legacy UNIX API /
  • include ltsignal.hgt
  • void (signal(int signo, void
    (handler)(int)))(int)
  • include ltsignal.hgt
  • void (sigset (int sig_no, void
    (handler)(int)))(int)
  • The second parameter of the signal system call
    is a pointer to a function that returns void and
    takes a single integer as its argument, and the
    return value of signal itself is a pointer to a
    function that returns void and takes a single
    integer argument.
  • The second parameter to signal is a pointer to
    the function to call whenever the signal is
    delivered.
  • The return value is the previous signal handler
    that was installed before the new one was added.

6
Signal Acceptance
  • Signals can be generated by outside events.
  • When a process receives a signal then the
    following actions can be taken
  • ignore the signal
  • terminate the process (the default action
    SIG_DFL)
  • process the signal - take a particular action

7
Signal Acceptance
  • Ignore the signal
  • Program that ignores control-C. When an INT
    signal (control-C) is
  • Received, the process ignores it (SIG_IGN is the
    handler)
  • include ltstdio.hgt
  • include ltsys/types.hgt
  • include ltsignal.hgt
  • int main (void)
  • signal (SIGINT, SIG_IGN)
  • while(1)
  • printf("Hello\n")

8
Signal Acceptance
  • 2. Terminate the process (the default action
    SIG_DFL)
  • Default action (see manual pages man signal) is
    the action executed if nothing else
  • include ltiostream.hgt
  • include ltsignal.hgt
  • int main()
  • signal(SIGINT, SIG_DFL) / catch signal
    SIGINT2 /
  • pause()
  • / wait for a signal interruption
    /

9
Signal Acceptance
  • 3. Handle the signal - Take a particular action
  • The target process executes the action associated
    with the signal.
  • Processing the signal depends also on the state
    of the process and level of priority. Signals can
    be caught by specifying a signal catching
    routine.
  • The signals SIGKILL and SIGSTOP are never caught
    and they always terminate a process.
  • include ltstdio.hgt
  • include ltsys/types.hgt
  • include ltsignal.hgt
  • void action (int sig)
  • signal (SIGINT, action)
  • printf ("control-C won't
    stop this
  • process!\n")

int main (void) signal (SIGINT,
action) while(1) printf("Hello\n")
10
Signal Handling Example
  • include ltstdio.hgt
  • include ltsignal.hgt
  • / signal handler function /
  • void action(int sig_no)
  • signal(sig_no, action)
  • fprintf(stderr,"Catch signal
    d\n", sig_no)
  • int main()
  • signal(SIGINT, action)
  • signal(SIGALRM, SIG_DFL)
  • signal(SIGTERM, SIG_IGN)
  • pause()
  • / wait for a signal interruption
    /

11
Alarm Handling
  • Alarm system function
  • Sets a timer for the caller process and generates
    SIGALRM (signal number 14) after the specified
    number of seconds have passed.
  • include ltunistd.hgt
  • unsigned alarm(unsigned
    nosec)

12
Alarm Handling
  • Example, alarm system calls cannot be stacked

alarm(10) alarm(20) // when this system call
is invoked // the previous pending // alarm
signal is canceled // the timer is set to 20sec
alarm(0) // this system call reset the timer,
// any pending alarm system
call is canceled
int main(void) alarm(20) while (1)
fprintf(stderr,"Hello\n")
13
Example of Handling Time-out Situations
  • include ltstdio.hgt
  • include ltunistd.hgt
  • include ltsignal.hgt
  • int main(void)
  • char buf256
  • int n
  • signal(SIGALRM, timeout)
  • alarm(30) // set timer
  • while ((nread(0,buf,sizeof(bu
    f))lt0)
  • alarm(0) // reset timer
  • exit(0)

void timeout() fprintf(stderr,"Timeout
error\n") exit(0)
14
Server Concurrency
  • For Servicing Multiple Clients there are two main
    approaches
  • forking with fork()
  • selecting with select()
  • fork() approach forks a new process to handle
    each incoming client connection
  • Issues with zombies created when parent loops
    back to accept() a new client (ignore SIGCHILD
    signal)
  • Inefficient ( high overhead due to context
    switching)
  • A better approach would be to have a single
    process handle all incoming clients, without
    having to spawn separate child server handlers.
    select().

15
I/O Multiplexing
  • Monitoring multiple descriptors
  • a server that handles both TCP and UDP
  • a generic TCP client (like telnet) need to be
    able to handle unexpected situations, such as a
    server that shuts down without warning.
  • Input from standard input should be sent to a TCP
    socket.
  • Input from a TCP socket should be sent to
    standard output.
  • Non-determinism and Concurrency Problem
  • How do we know when to check for input from each
    source?

16
Solutions for Concurrency and I/O Non-determinism
  • Use nonblocking I/O
  • use fcntl() to set O_NONBLOCK
  • Use alarm and signal handler to interrupt slow
    system calls.
  • Use multiple processes/threads.
  • Use functions that support checking of multiple
    input sources at the same time.

17
Non blocking I/O
  • use fcntl() to set O_NONBLOCK
  • include ltsys/types.hgt
  • include ltfcntl.hgt
  • int flags
  • flags fcntl(sock,F_GETFL,0)
  • fcntl(sock,F_SETFL,flags O_NONBLOCK)
  • Now calls to read() (and other system calls) will
    return an error and set errno to EWOULDBLOCK.

18
  • while (! done)
  • if ( (nread(STDIN_FILENO,)lt0))
  • if (errno ! EWOULDBLOCK)
  • / ERROR /
  • else write(tcpsock,)
  • if ( (nread(tcpsock,)lt0))
  • if (errno ! EWOULDBLOCK)
  • / ERROR /
  • else write(STDOUT_FILENO,)

19
The problem with nonblocking I/O
  • Using blocking I/O allows the Operating System to
    put the process to sleep when nothing is
    happening (no input). Once input arrives the OS
    will wake up the process and read() (or write()
    ) will return.
  • With nonblocking I/O the process will
    busy-wait, using inefficiently the CPU time

20
Using alarms
  • Time-out handling with alarms
  • signal(SIGALRM, sig_alrm)
  • alarm(MAX_TIME)
  • read(STDIN_FILENO,)
  • ...
  • signal(SIGALRM, sig_alrm)
  • alarm(MAX_TIME)
  • read(tcpsock,)
  • ...
  • Issues
  • How to assess the impact on response time ?
  • How to choose the value for MAX_TIME?

21
Handling Timeout when calling recvfrom()
  • Network Programming Aspects
  • Nondeterministic delay, when calling recvfrom()
    can be limited by generating an alarm signal
    after a specified period of time (even if there
    is no incoming datagram.)
  • We can do this by using SIGALRM and wrapping each
    call to recvfrom() with a call to alarm()

22
Handling Timeout when calling recvfrom()
  • signal(SIGALRM, sig_alrm)
  • alarm(max_time_to_wait)
  • if (recvfrom()lt0)
  • if (errnoEINTR)
  • / timed out /
  • else
  • / some other error /
  • else
  • / no error or time out
  • - turn off alarm /
  • alarm(0)

23
select()
  • The select() system call allows us to use
    blocking I/O on a set of descriptors (file,
    socket, ).
  • For example, we can ask select to notify us when
    data is available for reading on either STDIN or
    a TCP socket.

24
select()
  • int select( int maxfd,
  • fd_set readset,
  • fd_set writeset,
  • fd_set excepset,
  • const struct timeval timeout)
  • The select() system call provides a way for a
    single server to wait until a set of network
    connections has data available for reading
  • The advantage over fork() here is that no
    multiple processes are spawned
  • The downside is that the single server must
    handle state management on its own for all its
    new clients
  • Finite State Machine Client/Server Model

25
select()
  • include ltsys/time.hgt
  • int select( int maxfd,
  • fd_set readset,
  • fd_set writeset,
  • fd_set excepset,
  • const struct timeval timeout)
  • maxfd highest number assigned to a
    descriptor.
  • readset set of descriptors we want to read
    from.
  • writeset set of descriptors we want to write
    to.
  • excepset set of descriptors to watch for
    exceptions/errors.
  • timeout maximum time select should wait

26
select()
  • select() will return if any of the descriptors in
    readset and writeset of file descriptors are
    ready for reading or writing, respectively, or,
    if any of the descriptors in exceptset are in an
    error condition
  • The FD_SET(int fd, fd_set set) function will add
    the file descriptor fd to the set set
  • The FD_ISSET(int fd, fd_set set) function will
    tell you if filedescriptor fd is in the modified
    set set
  • select() returns the total number of descriptors
    in the modified sets
  • If a client closes a socket whose file descriptor
    is in one of your watched sets, select() will
    return, and your next recv() will return 0,
    indicating the socket has been closed

27
Setting the timeval in select()
  • Setting the timeout to 0, select() times out
    immediately
  • Setting the timeout to NULL, select() will never
    time out, and will block indefinitely until a
    file descriptor is modified
  • To ignore a particular file descriptor set, just
    set it to NULL in the call
  • select (max, readfds, NULL, NULL, NULL)
  • Here we only care about reading, and we want to
    block indefinitely until we do have a file
    descriptor ready to be read

28
struct timeval
  • struct timeval
  • long tv_sec / seconds /
  • long tv_usec / microseconds /
  • struct timeval max 1,0

29
fd_set
  • Implementation is not important
  • Operations to use with fd_set
  • void FD_ZERO( fd_set fdset)
  • void FD_SET( int fd, fd_set fdset)
  • void FD_CLR( int fd, fd_set fdset)
  • int FD_ISSET( int fd, fd_set fdset)

30
Using select()
  • Create fd_set
  • Clear the whole set with FD_ZERO
  • Add each descriptor you want to watch using
    FD_SET.
  • Call select
  • when select returns, use FD_ISSET to see if I/O
    is possible on each descriptor.

31
Other Unix API
  • Timers, Errors

32
Standard C library functions
  • lttime.hgt - declares set of functions for system
    clock query
  • time - sec since 01/01/70 (UNIX birth)
  • ctime - current local time
  • localtime
  • gmtime
  • asctime
  • mktime
  • clock - (ANSI C) , microsec since the process
    first called clock

33
Example lttime.hgt
  • // evaluate process execution time --- C
  • include ltiostream.hgt
  • include lttime.hgt
  • main()
  • time_t tick CLOCKS_PER_SECOND
  • clock_t start_time clock() // start timer
  • / process code here /
  • clock_t duration clock() - start_time
  • cout ltltDurationltlt(duration/tick)ltltendl
Write a Comment
User Comments (0)
About PowerShow.com