threads relatively fast lightweight processes by Wi6r8Piv

VIEWS: 1 PAGES: 24

									Operating Systems: Threads



                                            Threads
  • Process :
        – program in execution and its context
        – resources assigned to it
             » a virtual machine with memory - segments and pages, and high level facilities
             » open files, semaphores, buffers etc.
        – scheduling and dispatching
             » execution interleaved with other processes; priorities
             » volatile context of PC, Stack pointers, registers etc.
  • Threads :
        – multiple threads can exist within a single process
             » creation, deletion, synchronisation
        – can execute concurrently
             » thread priorities
             » multiprocessor machines

                                                                                               1
Operating Systems: Threads



  • Unit of resource ownership remains the process
        – all threads within a process share the same resources
             » virtual memory - all code and data, open files, pipes, sockets etc.
        – processes compete for resources from the kernel
        – threads must cooperate in using their resources
  • Unit of scheduling and dispatching becomes the thread
        – each thread needs its own volatile context
        – PC, stack and stack pointers, registers and status




                                                                                     2
Operating Systems: Threads



  • Threads can be created much more quickly than processes
        – no virtual machine to be created
        – just a new volatile context, stack area and registration with the scheduler
        – threads are typically created to run procedures within a program

  • Thread libraries available for most Operating Systems
        – Windows NT/2000, Solaris, Mach, OS/2
        – standard threads package - POSIX threads

  • Multi-threaded concurrent languages :
        – ADA, Occam
             » a thread per task
             » intercommunication by means of rendezvous
             » inter-thread message passing very efficient - via virtual memory
        – Java
             » extend Thread class in java.lang package

                                                                                        3
Operating Systems: Threads


  • Benefits of threads :
        – better programming paradigm for many applications
             » a thread for each inherently concurrent activity
             » simpler and more reliable programs
        – performance gains
             » example: less hold-up by blocking system calls
             » ability to use multi-processor systems easily and conveniently
                  - data can be partitioned to take advantage of multi-processing

        – real-time programs:
             » interrupts, signals and events occurring asynchronously
             » create a new thread for each asynchronous event as in happens
        – network servers:
             » servers handle multiple concurrent requests from network machines
             » create a thread to deal with each request separately

                                                                                    4
Operating Systems: Threads



        – distributed object servers in a network - CORBA object brokers
             » a thread per object
             » databases and transaction systems
        – dealing with multiple input sources and outputs
             » a thread per stream
        – user interaction:
             » foreground keyboard, mouse and screen interaction concurrent with
             background computation e.g. a spreadsheet
             » create separate threads for foreground and background
                  - a menu selection thread
                  - screen update and scrolling threads
                  - command execution thread

        – checkpoint threads
             » a background thread, executed periodically, that saves data
             » protects against crashes
                                                                                   5
Operating Systems: Threads



  • Example: a CS4 graphics project : A Virtual Orrery
        – each planet and moon represented by a thread
        – work out their own motions in cooperation with other threads
  • Example: a Network File Server
        – for each request from a user:
             » file directories accessed to get disc addresses
             » page faults will cause a hiatus - delaying later requests
             » server initiates disc transfers and waits for completion
             » disc device driver will reschedule transfers depending on head position
             » transfers may be completed out of order depending on disc rotation position
             » server has to remember all requested actions still outstanding and deal with
             completions in any order
             » effectively having to incorporate concurrency control into the server
        – much easier to start a new thread for each request
             » a thread held up for actions to complete does not hold up other threads
             » each thread a simple sequential series of actions

                                                                                              6
Operating Systems: Threads


                                 – service thread :
 Example: Pagemaker                 » initialisation - takes up idle time whilst
 DTP package                          creating and opening files
                                    » printing, importing data and “flowing” text
                                 – event-handing thread :
                                    » menu item selection
                                    » window operations
                                    » synchronising with service thread is tricky
                                        - user may continue to type, or use mouse,
                                        whilst service thread activity still in progress
                                        - user activity restricted by disabling menu
                                        items until service thread activities complete
                                 – screen-redraw thread :
                                    » allows redrawing to be aborted
  •three threads always active      » dynamic scrolling as user drags scroll bar
                                        - event-handling thread monitors scroll bar
                                        and redraws margin rulers
                                        - screen-redraw thread constantly monitors
                                        rulers and tries to redraw screen and catch up
                                                                                           7
Operating Systems: Threads



  • Solaris Threads :




        – kernel level threads
             » kernel knows nothing about user-level threads
             » only knows about kernel threads
             » can be multiplexed onto any processor
             » can be tied to run only on a specific processor
             » can be pinned to a specific processor
             » kernel threads for OS device drivers and other kernel functions
             » all scheduling done on kernel level threads
                                                                                 8
Operating Systems: Threads


        – lightweight processes (LWP)
             » one kernel thread per LWP
             » LWPs scheduled with associated kernel thread
                  - a pre-emptive priority-based scheduler
             » can have several LWPs per process
        – user-level threads
             » only user-level threads perform user’s work
             » each has to be connected to an LWP to be scheduled
                  - LWPs can be blocked
                  - need as many LWPs as number of concurrent kernel operations
             » can be multiplexed around available LWPs dynamically or tied to one
                  - does not require kernel interaction to do connection
                  - may have to wait for a free LWP to be connected to
             » can synchronise amongst themselves


                                                                                     9
Operating Systems: Threads



  • Solaris threads resource needs :
        – kernel threads :
             » small data structure and stack
             » context switching between kernel threads relatively fast
        – lightweight processes :
             » need a process control block (PCB)
             » may be quite slow
        – user level threads :
             » program counter, stack and pointer needed
             » no kernel resources involved
             » connecting user level threads to LWPs very fast
             » may be lots of user level threads and fewer LWPs
                  - kernel only sees LWPs




                                                                          10
Operating Systems: Threads



  POSIX Threads
  • system of choice for portability
        – similar to Solaris threads
        – incompatible with Microsoft Win32 NT threads!
  • textbook
        – Pthreads Primer - A Guide to Multithreaded Programming, Lewis & Berg
  • primitives :
      int pthread_create (pthread_t *ID, pthread_attr *attr, void *(*func)(void *ptr), void *arg);
      int pthread_join (pthread_t ID, void *arg);

      int pthread_mutex_init (pthread_mutex_t *m, pthread_mutex_attr *attr);
      int pthread_lock (pthread_mutex_t *m);
      int pthread_unlock (pthread_mutex_t *m);

      int pthread_cond_init (pthread_cond_t *c, pthread_cond_attr *attr);
      int pthread_cond_wait (pthread_cond_t *c, pthread_mutex_t *m);
      int pthread_cond_signal (pthread_cond_t *c);
      etc. etc.

                                                                                                     11
Operating Systems: Threads


  • Example : partitioned matrix multiplication :
        – partition each matrix into quarters:
          M1 :        A1 B1            M2 :      A2 B2
                      C1 D1                      C2 D2


          M1 * M2 =          A1*A2 + B1*C2 A1*B2 + B1*D2
                             C1*A2 + D1*C2 C1*B2 + D1*D2


        – multiplication procedure for each thread, written to deal with any quarters
        – thread procedure arguments passed by pointer to structures
             » first version uses separate argument structures for each thread
             » second version uses one structure but then needs to synchronise use of it by
             means of semaphores - just for demo purposes
             » also uses semaphores to synchronise thread termination
             » semaphore package built from mutex functions and condition variables
             » both versions do a normal N*N multiplication first for result comparison

                                                                                              12
Operating Systems: Threads

             #include <pthread.h>

            struct args { float (*p)[N]; int px0, py0; float (*q)[N]; int qx0, qy0; float (*r)[N]; int n2; };

            void fill_args (struct args *args_ptr,
               float (*p)[N]; int px0, py0; float (*q)[N]; int qx0, qy0; float (*r)[N]; int n2; ) {
               args_ptr->p = p; args_ptr->px0 = px0; args_ptr->q = q; args_ptr->qx0 = qx0;
               args_ptr->r = r; args_ptr->rx0 = rx0; args_ptr->n2 = n2;
            }

            void *matrix_mult (void *ptr) {
               float (*p)[N], (*q)[N], (*r)[N], sum;
               int px0, py0, qx0, qy0, n2, px, py, qx, qy, i, j;

               p = ((struct args *)ptr)->p; px0 = ((struct args *)ptr)->px0; py0 = ((struct args *)ptr)->py0;
               q = ((struct args *)ptr)->q; qx0 = ((struct args *)ptr)->qx0; qy0 = ((struct args *)ptr)->qy0;
               r = ((struct args *)ptr)->r; n2 = ((struct args *)ptr)->n2;

               for (px=px0; px<px0+n2; px++) {
                   for (qy=qy0; qy<qy0+n2; qy++) {
                       sum = 0;
                       for (py=py0, qx=qx0; py<py0+n2; py++, qx++) sum = sum+p[px][py]*q[qx][qy];
                       r[px][qy] = sum;
                   }
               }
        }
                                                                                                                13
Operating Systems: Threads

           main () {
            float p[N][N], q[N][N], r[N][N], r1[N][N], r2[N][N];
            pthread_t mmt, a1a2, b1c2, a1b2, b1d2, d1c2, c1,b2, d1d2;
            struct args mmt_args, a1a2_args, b1c2_args, a1b2_args, b1d2_args, c1a2_args,
                d1c2_args, c1b2_args, d1d2_args;
            int i, j;
            void *status;

             // arbitrary matrix values for testing
             for (i=0; i<N; i++) {
                 for (j=0; j<N; j++) {
                     p[i][j] = i*j; q[i][j] = i*j;
             }}

             // normal N*N multiplication first with one thread
             fill_args (&mmt_args, p, 0, 0, q, 0, 0, r, N);
             pthread_create (&mmt, NULL, matrix_mult, (void *)&mmt_args);

             // print results
             printf(“\nSingle thread result :\n”);
             for (i=0; i<N; i++) {
                 for (j=0; j<N; j++) {
                     printf(“%4.0f “, r[I][j]);
                 }
                 printf(“\n”);
             }
                                                                                           14
Operating Systems: Threads

                fill_args (&a1a2_args, p, 0, 0, q, 0, 0, r1, N/2);
                pthread_create (&a1a2, NULL, matrix_mult, (void *)&a1a2_args);

                fill_args (&b1c2_args, p, 0, N/2, q, N/2, 0, r2, N/2);
                pthread_create (&b1c2, NULL, matrix_mult, (void *)&b1c2_args);

                fill_args (&a1b2_args, p, 0, 0, q, 0, N/2, r1, N/2);
                pthread_create (&a1b2, NULL, matrix_mult, (void *)&a1b2_args);

                fill_args (&b1d2_args, p, 0, N/2, q, N/2, N/2, r2, N/2);
                pthread_create (&b1d2, NULL, matrix_mult, (void *)&b1d2_args);

                fill_args (&c1a2_args, p, N/2, 0, q, 0, 0, r1, N/2);
                pthread_create (&c1a2, NULL, matrix_mult, (void *)&c1a2_args);

                fill_args (&d1c2_args, p, N/2, N/2, q, N/2, 0, r2, N/2);
                pthread_create (&d1c2, NULL, matrix_mult, (void *)&d1c2_args);

                fill_args (&c1b2_args, p, N/2, 0, q, 0, N/2, r1, N/2);
                pthread_create (&c1b2, NULL, matrix_mult, (void *)&c1b2_args);

                fill_args (&d1d2_args, p, N/2, N/2, q, N/2, N/2, r2, N/2);
                pthread_create (&d1d2, NULL, matrix_mult, (void *)&d1d2_args);

                                                                                 15
Operating Systems: Threads

                 pthread_join (a1a2, &status);
                 pthread_join (b1c2, &status);
                 pthread_join (a1b2, &status);
                 pthread_join (b1d2, &status);
                 pthread_join (c1a2, &status);
                 pthread_join (d1c2, &status);
                 pthread_join (c1b2, &status);
                 pthread_join (d1d2, &status);

                 // final summation
                 for (i=0; i<N; i++) {
                      for (j=0; j<N; j++) {
                          r[I][j] = r1[I][j] + r2[I][j];
                      }
                 }

                 // print results
                 printf(“\nMultiple thread result :\n”);
                 for (i=0; i<N; i++) {
                     for (j=0; j<N; j++) {
                         printf(“%4.0f “, r[I][j]);
                     }
                     printf(“\n”);
                 }
             }

                                                           16
Operating Systems: Threads

                             typedef struct semaphore {
      Semaphore package :       pthread_mutex_t m;
                                pthread_cond_t c;
                                int count;
                             } sema_t;
                             void sema_init (sema_t *s) {
                                pthread_mutex_init (&s->m, NULL);
                                pthread_cond_init(&s->c, NULL);
                                s->count = 0;
                             }
                             void sema_P (sema_t *s) {
                                pthread_mutex_lock (&s->m);
                                while (s->count == 0) {
                                   pthread_cond_wait (&s->c, &s->m);
                                }
                                s->count--;
                                pthread_mutex_unlock (&s->m);
                             }
                             void sema_V (sema_t *s) {
                                pthread_mutex_lock (&s->m);
                                s->count++;
                                pthread_mutex_unlock (&s->m);
                                pthread_cond_signal (&s->c);
                             }

                                                                       17
Operating Systems: Threads

           #include <pthread.h>

          struct args {
              float (*p)[N]; int px0, py0; float (*q)[N]; int qx0, qy0; float (*r)[N]; int n2;
              sema_t *args_sem, *fin_sem
          };

          void fill_args ( struct args *args_ptr,
             float (*p)[N]; int px0, py0; float (*q)[N]; int qx0, qy0; float (*r)[N]; int n2;
             sema_t *args_sem, sema_t *fin_sem ) {
             args_ptr->p = p; args_ptr->px0 = px0; args_ptr->q = q; args_ptr->qx0 = qx0;
             args_ptr->r = r; args_ptr->rx0 = rx0; args_ptr->n2 = n2;
             args_ptr->args_sem = args_sem; args_pts->fin_sem = fin_sem;
          }




                                                                                                 18
Operating Systems: Threads



            void *matrix_mult (void *ptr) {
               float (*p)[N], (*q)[N], (*r)[N], sum;
               int px0, py0, qx0, qy0, n2, px, py, qx, qy, i, j;

               p = ((struct args *)ptr)->p; px0 = ((struct args *)ptr)->px0; py0 = ((struct args *)ptr)->py0;
               q = ((struct args *)ptr)->q; qx0 = ((struct args *)ptr)->qx0; qy0 = ((struct args *)ptr)->qy0;
               r = ((struct args *)ptr)->r; n2 = ((struct args *)ptr)->n2;

               // signal that arguments have been copied out
               sema_V (((struct args *)ptr)->args_sem);

               for (px=px0; px<px0+n2; px++) {
                   for (qy=qy0; qy<qy0+n2; qy++) {
                       sum = 0;
                       for (py=py0, qx=qx0; py<py0+n2; py++, qx++) sum = sum+p[px][py]*q[qx][qy];
                       r[px][qy] = sum;
                   }
               }

               // signal that this thread has finished
               sema_V (((struct args *)ptr)->fin_sem);

        }


                                                                                                                19
Operating Systems: Threads

     main () {
       float p[N][N], q[N][N], r[N][N], r1[N][N], r2[N][N];
       pthread_t mmt, a1a2, b1c2, a1b2, b1d2, d1c2, c1,b2, d1d2;
       struct args mmt_args;
       int i, j, t;
       void *status;
       sema_t args_sem, fin_sem;

         // arbitrary matrix values for testing
         for (i=0; i<N; i++) {
             for (j=0; j<N; j++) {
                 p[i][j] = i*j; q[i][j] = i*j;
         }}

         sema_init (&args_sem);
         sema_init (&fin_sem);

         // normal N*N multiplication first with one thread
         fill_args (&mmt_args, p, 0, 0, q, 0, 0, r, N, &args_sem, &fin_sem);
         pthread_create (&mmt, NULL, matrix_mult, (void *)&mmt_args);
         sema_P (&args_sem);            // wait until arguments copied
         sema_P (&fin_sem);             // wait until thread finished

         // print results
         . . . . etc.

                                                                               20
Operating Systems: Threads


             fill_args (&mmt_args, p, 0, 0, q, 0, 0, r1, N/2, &args_sem, &fin_sem);
             pthread_create (&a1a2, NULL, matrix_mult, (void *)&mmt_args);
             sema_P (&args_sem);               // wait until arguments read

             fill_args (&mmt_args, p, 0, N/2, q, N/2, 0, r2, N/2, &args_sem, &fin_sem);
             pthread_create (&b1c2, NULL, matrix_mult, (void *)&mmt_args);
             sema_P (&args_sem);

             fill_args (&mmt_args, p, 0, 0, q, 0, N/2, r1, N/2, &args_sem, &fin_sem);
             pthread_create (&a1b2, NULL, matrix_mult, (void *)&mmt_args);
             sema_P (&args_sem);

             fill_args (&mmt_args, p, 0, N/2, q, N/2, N/2, r2, N/2, &args_sem, &fin_sem);
             pthread_create (&b1d2, NULL, matrix_mult, (void *)&mmt_args);
             sema_P (&args_sem);

             fill_args (&mmt_args, p, N/2, 0, q, 0, 0, r1, N/2, &args_sem, &fin_sem);
             pthread_create (&c1a2, NULL, matrix_mult, (void *)&mmt_args);
             sema_P (&args_sem);

             . . . . . . . . etc.

             for (t=0; t<8; t++) sema_P (&fin_sem);        // wait for all threads to finish

             // final summation and print results etc.
             .......
                                                                                               21
Operating Systems: Threads


  Java Threads
  • Example showing interleaved thread execution :

             class SimpleThread extends Thread {
                public SimpleThread (String str) {         // superclass constructor
                   super (str);
                }

                 public void run () {
                   for (int i=0; i<10; i++) {
                       System.out.println (i + “ “ + getName() );
                       try { sleep ((int) (Math.random () * 1000));
                       catch (InterruptedException e) { }
                   }
                   System.out.println (“Finished “ + getName () );
                 }
             }

             class TwoThreadsTest {
                public static void main (String[ ] args) {
                   new SimpleThread (“Edinburgh”).start ();
                   new SimpleThread (“Glasgow”).start ();
                }
             }
                                                                                       22
Operating Systems: Threads



        – main method starts two threads by calling the start method
             » output something like :
                       0 Edinburgh
                       0 Glasgow
                       1 Glasgow
                       1 Edinburgh
                       2 Edinburgh
                       3 Edinburgh
                       2 Glasgow
                       3 Glasgow
                       4 Glasgow
                       4 Edinburgh
                       5 Glasgow
                       5 Edinburgh
                       6 Glasgow
                       7 Glasgow
                       8 Glasgow
                       6 Edinburgh
                       7 Edinburgh
                       8 Edinburgh
                       9 Edinburgh
                       Finished Edinburgh
                       9 Glasgow
                       Finished Glasgow
                                                                       23
Operating Systems: Threads


     Windows NT Threads
        – initial thread built automatically for a process
             » more created through calls to thread library
        – each thread has its own user and kernel stacks
        – 32 levels of priority (Java threads only have 10)
             » pre-emptive priority scheduler
             » threads can change their priority within limits
        – mutual exclusion locks between threads
             » between processes and within one process
        – event objects for synchronisation
        – semaphores with resource counts
             » more than one thread can get a semaphore when multiple resources
             controlled by it
        – fibers in NT Version 4 onwards
             » finer user control of scheduling
        – all other threads signalled when one terminates

                                                                                  24

								
To top