  Linux Threads Programming

  Matteo Dell'Omodarme matt@martine2.difi.unipi.it 

   hermes44@secsm.org ű
  1999 12 7

  ______________________________________________________________________

  

  1. ణ ̷
     1.1 Ұ
     1.2  ΰ?
     1.3 ڼ(atomicity) ֹ߼(volatility)
     1.4 Lock ()

  2. ׸ ణ 
     2.1 pthread.h 
     2.2 lock ʱȭ
     2.3  ϱ
     2.4  
     2.5  ƾ  ϱ
     2.6  ڵ 

  ______________________________________________________________________

  1.  ణ ̷

  1.1.  Ұ

  LinuxThreads   α׷   ̺귯̴.
  LinuxThreads Ŀ  带 Ѵ;  clone()
  ý(system call)    ٸ Ŀο
  ̷.  Posix 1003.1c API Ͽ Ŀ 2.0.0̻ Ŀΰ
   C ̺귯  ִ   ýۿ Ѵ.

  1.2.   ΰ?

   α׷    帧̴. ׷  
  α׷   尡  α׷ ÿ ϴ 
  α׷  ̴.

    α׷  尡  ޸  (׸ 
  ũͿ  Ϻ ý ڿ) ϴ н Ÿ 
  μ̰ ٸ. ſ н μ  ڽŸ 
  ޸𸮻 Ѵ. ׷  μ    
  ȯ(context switch)  μ   ȯ 
  ϴ.

  带 ϴ   ֿ  ִ:

  o   α׷ ϳ  帧 ٴ  ϴ 
      ۼ  ְ    ִ. (, )

  o   μ ýۿ,   μ󿡼 
       ִ. ̴  α׷ ٸ μ ۾ й 
     ְ ش. ̷ α׷    CPU   ִ 
      α׷  ξ  .

  1.3.  ڼ(atomicity) ֹ߼(volatility)

  忡  Ǵ ޸𸮸 ϴ   ǰ ʿϴ.
   α׷ Ϲ  ޸ó  ޸ ü  
   ̴.

  ڼ(atomicity)  ü   и  , ͷƮ
  Ǵ ʴ  ̷ Ǵٴ  Ѵ.  ޸𸮻
  Ϳ    ̷  . Դٰ GCC
  Ϸ  Ϳ    ۸ϴ ȭ
   ̴.  ̷ ޸  ϴ ̶  μ
     Ǵ    ־߸ Ѵ.

  Ϳ  ޸  ۸ϴ GCC ȭ   
  ޸   ü volatile Ӽ Ÿ Ǿ Ѵ. 
  word volatile ü а    ̷  ̴.

  1.4.  Lock ()

   о ϴ   ޸ ̴: ++i ׻
   ޸  i 1ŭ Ű ʴ´.   ̿ ٸ
  μ i   ֱ ̴. ׷  μ  
  ++i Ѵٸ 2 ƴ 1   ִ.

  ׷  尡   ٲٴ  ٸ 尡  
   ۾    ϴ ý ʿϴ. ̴ Ʒ  lock
   ȴ.     ٲٴ ƾ ϴ 
  尡 ִٰ  .  ƾ Ȯ   ؼ
    ؾ Ѵ.

  o  i   lock Ǵ.

  o     Ѵ.

  o  lock Ѵ.

     lock ɸ   lock  常   ٲ 
  ִ.   ٸ    ̴.   ؼ
     ϳ lock Ǳ ̴. ù° 尡 lock
     ι° 尡 lock   ִ.     
  ̿ϴ  ٸ μ Ȱ   𸥴. 
  Ϲ   ĳø ̿Ѵ.

  2.  ׸ ణ 

  2.1.  pthread.h 

  LinuxThreads ϴ   ƾ Ÿ ϴ
  /usr/include/pthread.h  ؼ ̿ ϴ.

    α׷ ۼ ⺻  ܰ ̴:

  o   鿡 lock ɰ 带   pthread ƾ
     Ѵ.

  o    ƾ Ѱܾ   ڵ ϴ ü
     .

    ⺻ pthread.h ƾ  ϸ鼭   ܰ踦
  캸.

  2.2.  lock ʱȭ

  ؾ߸ ϴ ù° ൿ  ϳ  lock ʱȭϴ ̴.
  POSIX lock pthread_mutex_t Ÿ  ȴ;  lock
  ʱȭϱ   ƾ ȣ ʿ䰡 ִ:

       int pthread_mutex_init(pthread_mutex_t *mutex,
       const pthread_mutexattr_t *mutexattr);

   :

       #include <pthread.h>
       ...
               pthread_mutex_t lock;
               pthread_mutex_init(&lock, NULL);
       ...

  pthread_mutex_init Լ mutex ڰ Ű mutex ü
  mutexattr  õ mutex Ӽ  ʱȭ Ѵ. mutexattr
  NULL̸, Ʈ Ӽ ȴ.

  ؼ  ʱȭ lock  ϴ ڴ.

  2.3.   ϱ

  POSIX  带 Ÿ  ڰ pthread_t Ÿ 
  ϵ Ѵ.  ȣ 尡 ȴ:

       int pthread_create(pthread_t *thread, pthread_attr_t *attr, void
       *(*start_routine)(void *), void *arg);

  Ѵٸ    id thread ڰ  
   ǰ 0 ϵȴ.  ߻ϸ 0 ƴ  ϵȴ.

  f() ƾ ϴ 带  f() arg  Ű ͸
  ѱ ؼ   Ѵ:

       #include <pthread.h>
       ...
               pthread_t thread;
               pthread_create(&thread, NULL, f, &arg).
       ...

  f()    Ÿ  Ѵ:

       void *f(void *arg);

  2.4.   

   ܰ f() ƾ  ϱ    尡 
    ٷ Ѵ.  ȣѴ:

       int pthread_join(pthread_t th, void **thread_return);

  th  Ű 尡    Լ ȣ 
   .  thread_return NULL̴ϸ th ϰ
  thread_return Ű  ȴ.

  2.5.   ƾ  ϱ

  ȣ ƾ   ƾ ѱ    ִ:

  o   

  o  ü

  ι°  ڵ ⼺(modularity) ϴ   
  ̴.  ü   ܰ  ؾ Ѵ; ù° 
   lock鿡  , ι° ƾ ʿ ϴ 
  Ϳ  , ° 带 ִ id 尡 ̿
   ִ CPU    (Ÿӿ   ϴ  
  ).  ü ù°  캸; Ѱ   
   Ǵ ̾ Ѵ. ׷ ʿ  lock
  ͸  ؾ Ѵ. double Ÿ   var   
  lock ѱ  ü    ߸ Ѵ:

  double volatile *var;
  pthread_mutex_t *var_lock;

  volatile Ӽ  ġ ָ϶. ̴  ü ƴ϶ var
  volatile Ÿ.

  2.6.   ڵ 

  带 ̿Ͽ  ȭ   ִ α׷   
  Įڰ ̴.  ּ  ڵ带 Ѵ.

  /*  Ϸ gcc  -D_REENTRANT -lpthread */

  #include <stdio.h>
  #include <pthread.h>

  /* ˸ ü  */
  typedef struct {
          double volatile *p_s;      /* Į    */
          pthread_mutex_t *p_s_lock; /*  s lock */
          int n;                     /*   */
          int nproc;                 /* ̿  ִ μ  */
          double *x;                 /* ù°   */
          double *y;                 /* ι°   */
          int l;                     /*   */
  } DATA;

  void *SMP_scalprod(void *arg)
  {
          register double localsum;
          long i;
          DATA D = *(DATA *)arg;

          localsum = 0.0;

          /*   i = D.n  Į  Ѵ.
             D.n = 1, 2, ...
             D.nproc  ´. Ȯ D.nproc 尡 ֱ
              i   D.nproc̴. */

          for(i = D.n; i < D.l; i += D.nproc)
          localsum += D.x[i]*D.y[i];

          /* s  lock Ǵ ... */
          pthread_mutex_lock(D.p_s_lock);

          /* ... s  ٲ۴. ... */
          *(D.p_s) += localsum;

          /* ... ׸ lock Ѵ. */
          pthread_mutex_unlock(D.p_s_lock);

          return NULL;
  }

  #define L 9     /*   */

  int main(int argc, char **argv)
  {
          pthread_t *thread;
          void *retval;
          int cpu, i;
          DATA *A;
          volatile double s = 0; /*   */
          pthread_mutex_t s_lock;
          double x[L], y[L];

          if (argc != 2) {
                  printf("usage: %s <number of CPU>\n", argv[0]);
                  exit(1);
          }

          cpu = atoi(argv[1]);
          thread = (pthread_t *) calloc(cpu, sizeof(pthread_t));
          A = (DATA *) calloc(cpu, sizeof(DATA));

          for (i = 0; i < L; i++)
          x[i] = y[i] = i;

          /* lock  ʱȭѴ. */
          pthread_mutex_init(&s_lock, NULL);

          for (i = 0; i < cpu; i++) {
                  /* ü ʱȭѴ. */
                  A[i].n = i; /*   */
                  A[i].x = x;
                  A[i].y = y;
                  A[i].l = L;
                  A[i].nproc = cpu; /* CPU  */
                  A[i].p_s = &s;
                  A[i].p_s_lock = &s_lock;

                  if (pthread_create(&thread[i], NULL, SMP_scalprod,
                      &A[i])) {
                          fprintf(stderr, "%s: cannot make thread\n",
                                  argv[0]);
                          exit(1);
                  }
          }

          for (i = 0; i < cpu; i++) {
                  if (pthread_join(thread[i], &retval)) {
                          fprintf(stderr, "%s: cannot join thread\n",
                                  argv[0]);
                          exit(1);
                  }
          }

          printf("s = %f\n", s);
          exit(0);
  }

  Copyright  1999, Matteo Dell'Omodarme

  Published in Issue 48 of Linux Gazette, December 1999

