Advertisement
Guest User

Untitled

a guest
Jun 22nd, 2017
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.79 KB | None | 0 0
  1.  /* This exmple illustrates the use of mutex variables in a thread program that performs
  2. * a dot product. The main data is made available to all threads though a globally accessible
  3. * structure Each thread works on a different part of the data. The main thread waits for all
  4. * the threads to compete their computations, and then it prints the resulting sum
  5. */
  6.  
  7. #include <pthread.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10.  
  11. /* The structure containing the necessary information to allow the function
  12. * "dotprod" to access its input data and place its output into the structure
  13. */
  14.  
  15. typedef struct
  16. {
  17.  double *a;
  18.  double *b;
  19.  double sum;
  20.  int veclen;
  21. }DOTDATA;
  22.  
  23. /*Globally accessible variables and a mutex*/
  24. #define NUMTHRDS 4
  25. #define VECLEN 100
  26.  
  27. //structure variable
  28. DOTDATA dotstr;
  29. //pthread_t is an opaque type which acts as a handle for the new thread
  30. pthread_t callThd[NUMTHRDS];
  31. //a mutex variable
  32. pthread_mutex_t mutexsum;
  33.  
  34. /* The function dotprod is activated when the thread is created.
  35. * All input to this routine is obtained from a structure of type
  36. * DOTDATA(shared data) and all output from this function is written
  37. * into this structure. The benefit of this approach is apparent for the
  38. * multi-thread program: when a thread is created we pass a single argument
  39. * to the activated function - typically this argument is a thread number. All
  40. * the other information required is accessed from the globally accessible strcture
  41. */
  42. void *dotprod(void *arg)
  43. {
  44.  //local variables
  45.  int i, start, end, len;
  46.  long offset;
  47.  double mysum, *x, *y;
  48.  offset = (long) arg;
  49.  
  50.  len = dotstr.veclen;
  51.  start = offset * len;
  52.  end = start + len;
  53.  x = dotstr.a;
  54.  y = dotstr.b;
  55.  
  56.  /*
  57.  Perform the dot product and assign result
  58.  to the appropriate variable in the structure
  59.  */
  60.  mysum = 0;
  61.  for(i = start; i < end; i++)
  62.  {
  63.   mysum += (x[i] * y[i]);
  64.  }
  65.  
  66.  /*
  67.  Lock a mutex prior to updating the value in the shared
  68.  structure, and unlock it upon updating
  69.  */
  70.  pthread_mutex_lock(&mutexsum);
  71.  dotstr.sum += mysum;
  72.  pthread_mutex_unlock(&mutexsum);
  73.  
  74.  pthread_exit((void*) 0);
  75.  
  76.  return 0;
  77. }
  78.  
  79. /*
  80. The main program creates threads which do all the work and then
  81. print out result upon completion. Before creating the threads, the
  82. input data is created. Since all threads update a shared structure,
  83. we need a mutex for mutual exclusion. The main thread needs to wait for
  84. all threads to complete, it waits for each one of the threads. We specify
  85. a thread attribute value that allow the main thread to join with the
  86. threads it creates. Note also that we feed up handles when they are no
  87. longer needed.
  88. */
  89. int main(int argc, char *argv[])
  90. {
  91.  long i;
  92.  double *a, *b;
  93.  void *status;
  94.  pthread_attr_t attr;
  95.  
  96.  a = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double));
  97.  b = (double*) malloc (NUMTHRDS*VECLEN*sizeof(double));
  98.  
  99.  for (i=0; i<VECLEN*NUMTHRDS; i++)
  100.  {
  101.   a[i]=1.0;
  102.   b[i]=a[i];
  103.  }
  104.  
  105.  dotstr.veclen = VECLEN;
  106.  dotstr.a = a;
  107.  dotstr.b = b;
  108.  dotstr.sum=0;
  109.  
  110.  pthread_mutex_init(&mutexsum, NULL);
  111.  
  112.  /* Create threads to perform the dotproduct  */
  113.  pthread_attr_init(&attr);
  114.  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
  115.  
  116.  for (i = 0; i < NUMTHRDS; i++)
  117.  {
  118.   /*
  119.   Each thread works on a different set of data.
  120.   The offset is specified by 'i'. The size of the
  121.   data for each thread is indicated by VECLEN
  122.   */
  123.   pthread_create(&callThd[i], &attr, dotprod, (void *)i);
  124.   printf("In main: creating thread %ld\n", i);
  125.  }
  126.  
  127.  pthread_attr_destroy(&attr);
  128.  
  129.  /* Wait on the other threads */
  130.  for(i=0; i<NUMTHRDS; i++)
  131.  {
  132.   pthread_join(callThd[i], &status);
  133.  }
  134.  
  135.  /* After joining, print out the results and cleanup */
  136.  printf ("Sum =  %f \n", dotstr.sum);
  137.  free (a);
  138.  free (b);
  139.  pthread_mutex_destroy(&mutexsum);
  140.  pthread_exit(NULL);
  141.  
  142.  return 0;
  143. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement