I/O Multiplexing & Threads

 

·       Select

·       Concurrent Client

·       Concurrent TCP Server Using Select

·       Poll

·       Concurrent TCP Server Using Poll

·       Threads & Synchronization

·       Shared Memory & Forking

 


 

âSelect:

 

n = select ( length, readset, writeset, exceptset, time)

 

values of  time:

 

       NULL      indifinate wait
          0            no-wait  (poll)
                    wait T  (sec + micro-sec)


Under what conditions a descriptor is ready?

ü ready for reading:

§  Receive buffer has data > low-water mark

(default is 1, set SO_RCVLOWWAT socket option to change).

§  Receive FIN from the other side.

§  A listen socket has a completed connection.

§  An error condition (e.g., receive RST ).

ü ready for writing:

§  Send buffer has space  > low-water mark

   (default is 2048, set SO_SNDLOWWAT socket option to change).

§  Sent FIN out (close write end).

§  An error condition.

ü ready for exception condition:

E.g., out-of-band date is received

 

 

 

 


âConcurrent Client

 

Example1:  echo client:

  strcliselect01.c   &  it is used in tcpcli01.c

 

  Server: (run an echo server at port 10111, defined in “unp.h”)
      % cd  /home/cs779/stevens3rd.book/unpv13e/tcpcliserv
      % tcpserv01

  Client:
      % cd  /home/cs779/stevens3rd.book/unpv13e/select
        %   tcpcli01 127.0.0.1
       %  tcpcli01 127.0.0.1 
< infile  > outfile

      Problem:
      infile is NOT the same as outfile,   since we exit when stdin is done:

   if (Fgets(sendline, MAXLINE, fp) == NULL)  return;      

        

Example2:

 strcliselect02.c   &  it is used in tcpcli02.c
 The Problem above is fixed (use of  shutdown):


         % tcpcli02  127.0.0.1   < infile  > outfile

          if (Fgets(sendline, MAXLINE, fp) == NULL) {

          stdineof = 1;

          Shutdown(sockfd, SHUT_WR);   /* send FIN */

 



 

âConcurrent TCP Server using Select

 

ü Example3: tcpservselect01.c

 

Server:

      % cd  /home/cs779/stevens3rd.book/unpv13e/tcpcliserv
      % tcpservselect01

 

Client:

      % cd  /home/cs779/stevens3rd.book/unpv13e/tcpcliserv
      %   tcpcli01 127.0.0.1
     
(repeat for as many clients as you like)


     Problem: denial of service attack
          

%   tcpcli012  127.0.0.1

 

    The user sends data without newline,

    The server will hung (blocked) forever!

 

 tcpcli012  uses  

 str_cli12.c  (this program dos not send newline!)

 



 

 


âPoll:

 

struct pollfd   client[MaxNofds];

 

client[i].fd = sockfd;

client[i].events = POLLRDNORM;

 

n = poll (struct  pollfd    client[], nfds_t  sizefds,  int  timeout);

 

values of timeout:


       INFTIM     indifinate wait

          0          no-wait  (poll)
         T          T  millisec


  if (client[i].revents & POLLRDNORM) {

          read (sockfd, ….);

  }

 

 


âConcurrent TCP Server using Poll



ü Example4: tcpservpoll01.c

 

Server:

      % cd  /home/cs779/stevens3rd.book/unpv13e/tcpcliserv
      % tcpservpoll01

 

Client:

        % cd  /home/cs779/stevens3rd.book/unpv13e/tcpcliserv
        %   tcpcli01 127.0.0.1 OR telnet 127.0.0.1  10111
             
(repeat for as many clients as you like)

 

 




 

âThreads & Synchronization


 

Thread Functions:

pthread_create  (ThreadID, Priority, Starting Fun, Fun Args)

pthread_join    // similar to waitpid

pthread_self     // similar to getpid

pthread_detach  // not joinable

pthread_exit     // terminate a thread;

// calling exit() kills ALL threads.
 
 

Simple Exampls:

à   tcpcli01.c uses (strclithread.c)  & 

à   tcpserv01.c

 

 

Synchronization Functions:

    

pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;

 

Pthread_mutex_lock (&mutex1);

 

       { Critical Section}

 

Pthread_mutex_unlock (&mutex1);

 

Simple Exampl:

àThreadMutex.c

 

 




 

 

âShared Memory & Forking


 

Functions:

The Process first creates shared memory segment and then attach to it:

segment id = shmget (IPC_PRIVATE, size, S_IRUSR | S_IWUSR);

char *sharedString = (char *) shmat (id, NULL, 0);

 

·       The process could write/read to/from the shared memory:

sprintf (shareString, "Writing to shared memory");

printf("%s", sharedStringy);

 

·       When done a process can detach the shared memory from its address space:

shmdt (sharedString);

 

 

Example: shmfork.c

#define SIZE 10

int
main()
{
   int             segment_id = shmget(IPC_PRIVATE, SIZE * sizeof(int), S_IRUSR | S_IWUSR);
   int            *sharedVar = (int *) shmat(segment_id, NULL, 0);
   int            *nonsharedVar = (int *) malloc(SIZE * sizeof(int));


   int             i;

   for (i = 0; i < SIZE; i++) {
      sharedVar[i] = 0;
      nonsharedVar[i] = 0;
   }


   if (fork() == 0) {
      for (i = 0; i < SIZE; i++) {
         sharedVar[i] += i;
         nonsharedVar[i] += i;
      }
      printf("\nChild : shared variables:- ");
      for (i = 0; i < SIZE; i++)
         printf("%d ", sharedVar[i]);
      printf(" non-shared variables:- ");
      for (i = 0; i < SIZE; i++)
         printf("%d ", nonsharedVar[i]);

      exit(0);
   }
   wait(NULL);

   printf("\nParent: shared variables:- ");
   for (i = 0; i < SIZE; i++)
      printf("%d ", sharedVar[i]);
   printf(" non-shared variables:- ");
   for (i = 0; i < SIZE; i++)
      printf("%d ", nonsharedVar[i]);
   printf("\n");
}