CPS 346 & 444/544 Lecture notes: Threads



Coverage: [OSCJ] Chapter 4 (pp. 133-165), and [USP] Chapter 2 (pp. 21-23, 31-48) and Appendix A.5 (pp. 812-814)


Overview



(ref. [OSIDP] Fig. 4.1 on p. 162; image courtesy [OSIDP] webpage)


Introduction

A thread is
  • an ADT within a process
  • has its own stack, program counter value, register set, and state
  • share process resources

  • (heavyweight) process vs. (lightweight) thread

  • We also have a thread control block (TCB).


    Relationship between process and thread states



    (ref. [OSIDP] Fig. 4.7 on p. 170; image courtesy [OSIDP] webpage)
  • variables are either static (exist for the life of the process) or automatic (allocated/deallocated on block entry/exit)

  • Declarations and definitions

    • defining a variable entails allocating storage for it (once per program)
    • declaring a variable entails announcing its type so that it can be used
    • every definition is also a declaration (e.g., the definition int x; is also a declaration)
    • some declarations are not definitions (e.g., the declaration extern int x; is not a definition)


    extern modifier in C

      /* x.c */
      
      int x = 10;
      #include<stdio.h>
      
      /* main.c */
      
      extern int x;
      
      main() {
         printf("%d\n", x);
      }
      


    Storage and linkage classes

    • storage classes
      • static storage: once allocated, persists throughout lifetime of program (e.g., a global variable)
      • automatic storage: allocated and deallocated on block/function entry and exit, resp. (e.g., a variable local to a function)
    • linkage classes
      • internal linkage: visible only within defining file
      • external linkage: visible outside of defining file as well as within it

    • statics and externals have 0 as a default value
    • automatics have no default value


    Storage class summary

    classscopelifestorage init. arrays/structsdefault value
    automaticblockblock activestackyesundefined
    register (1)blockblock activemachine registernoundefined (2)
    external (3)declaration to end-of-filepermanentdata areayes0
    static external (4)declaration to end-of-filepermanentdata areayes0
    static internalblockpermanentdata areayes0

    notes:
    1. speed advantage
    2. for function arguments, value passed
    3. can be accessed from other files
    4. cannot be accessed from other files
    (ref. [C])


    static modifier in C

    • can you write an object-oriented program in C?
    • before a variable within a function
      • if present, static storage
      • if absent, automatic storage (default)
    • before a variable outside of a function
      • if present, internal linkage (like private in OO languages)
      • if absent, external linkage (default)
    • before a function
      • if present, internal linkage (like private in OO languages)
      • if absent, external linkage (default)


    static modifier summary

    (courtesy Robbins & Robbins' [USP] Chapter 2 webpage)


    • variables:
      where declared static modifies static applied? storage class linkage class
      inside a function storage class yes static none
      inside a function storage class no automatic none
      outside any function linkage class yes static internal
      outside any function linkage class no static external

      (ref. [USP] Table A.3, p. 814; HTML table courtesy Robbins & Robbins' [USP] Chapter 2 webpage)

    • functions:
      static modifies static applied? linkage class
      linkage class yes internal
      linkage class no external

      (HTML table courtesy Robbins & Robbins' [USP] Chapter 2 webpage)


    Summary of static reserved word

      static keyword used in a variable declaration:

      outside of any function:
         /* x is static data and allocated in the static region of the memory image,
            and it has external linkage */
      
         /* linkage class: ?
            storage class: ? */
         int x;
      
         /* x is STILL static data, but now has internal linkage and thus cannot be
            referenced by another module (.o file) */
      
         /* akin to "private" in C++ or Java */
      
         /* linkage class: ?
            storage class: ? */
         static int x;
      
      inside of any function:
         void f() {
      
            /* x is allocated on the stack (i.e., it is not static data) and
               this particular x can only be referenced within the body of
               this function */
      
            /* linkage class: ?
               storage class: ? */
            int x;
      
            /* x is now static data and allocated in the static region of the memory
               image */
      
            /* linkage class: ?
               storage class: ? */
            static int x;
         }
      
      static keyword used in a function definition/declaration:
         /* f() has external linkage and thus can be referenced by another module
            (i.e., .o file) */
      
         /* linkage class: ?
            storage class: ? */
         void f();
      
         /* f() has internal linkage and thus cannot be referenced by another module
            (i.e., .o file) */
      
         /* linkage class: ?
            storage class: ? */
         void static f();
      


    Bubblesort storage class exercise

    • for each object and function in the following code, give the storage and linkage class where appropriate
    • ref. [USP] program 2.5 (p. 41) and exercise 2.20 (p. 42)
    • /* a function which sorts an array of integers and
         counts the number of interchanges made in the process */
      static int count = 0;
      
      /* return true if interchanges are made */
      static int onepass (int a[], int n) {
         int i;
         int interchanges = 0;
         int temp;
      
         for (i = 0; i < n-1; i++)
            if (a[i] > a[i+1]) {
               temp = a[i];
               a[i] = a[i+1];
               a[i+1] = temp;
               interchanges = 1;
               count++;
            }
         return interchanges;
      }
      
      void clearcount (void) {
         count = 0;
      }
      
      int getcount (void) {
         return count;
      }
      
      /* sort a in ascending order */
      void bubblesort (int a[], int n) {
         int i;
         for (i = 0; i < n-1; i++)
            if (!onepass (a, n-i))
               break;
      }
      
    • count is a static variable with internal linkage (note use of static modifier for linkage, not storage)
    • all other variables use automatic storage with no linkage
    • onepass does not have a storage class; its linkage is internal
    • all other functions have external linkage; functions do not have a storage class


    Synchronization


    Thread-safe functions

    • static variables make the use of multiple threads unsafe
    • char* strtok (char* restrict s1, const char* restrict delimiter);
      • first and subsequent calls are different
      • tokenizes string in place (i.e., does not allocate new space for tokens)
      • strtok is not thread-safe because it uses a static pointer
      • graphical depiction of string before and after call to strtok

        before:



        (regenerated with minor modifications from [USP] Fig. 2.3, p. 36)

        after:



        (regenerated with minor modifications from [USP] Fig. 2.4, p. 36)

      • index into the string being tokenized (e.g., wordcount, wordaverage)
      • use POSIX thread-safe function strtok_r (_r stands for reentrant)
      • moral of the story: avoid using static storage


    makeargv

    • ref. [USP] §2.6 (pp. 31-38)
    • three versions
      • char** makeargv (char* s);
      • int makeargv (char* s, char*** argvp);
      • int makeargv (const char* s, const char* delimiters, char*** argvp);
    • for instance, ./a.out -c tom and -m jerry
    • importance of cleaning up after yourself; [USP] example 2.19 on p. 38 (freemakeargv.c)
    • [USP] exercise 2.24 on p. 51 (getpaths.c)


    Self-study

    • re-read [USP] §2.9 (pp. 42-48)
    • download, compile, and run codes
    • convince yourself you understand how the list works
    • exercise in implementing the third version of makeargv


    References

      [COPL] R.W. Sebesta. Concepts of Programming Languages. Addison-Wesley, Boston, MA, Sixth edition, 2003.
      [OSCJ] A. Silberschatz, P.B. Galvin, and G. Gagne. Operating Systems Concepts with Java. John Wiley and Sons, Inc., Seventh edition, 2007.
      [OSIDP] W. Stallings. Operating Systems: Internals and Design Principles. Prentice Hall, Upper Saddle River, NJ, Sixth edition, 2009.
      [USP] K.A. Robbins and S. Robbins. UNIX Systems Programming: Concurrency, Communication, and Threads. Prentice Hall, Upper Saddle River, NJ, Second edition, 2003.

    Return Home