Back to index

glibc  2.9
Defines | Functions | Variables
ex3.c File Reference
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <pthread.h>

Go to the source code of this file.

Defines

#define NUM_THREADS   5

Functions

void * search (void *)
void print_it (void *)
int main (int argc, char **argv)

Variables

pthread_t threads [NUM_THREADS]
pthread_mutex_t lock
int tries
volatile int started

Define Documentation

#define NUM_THREADS   5

Definition at line 12 of file ex3.c.


Function Documentation

int main ( int  argc,
char **  argv 
)

Definition at line 24 of file ex3.c.

{
  int i;
  int pid;

  /* create a number to search for */
  pid = getpid();
  printf("Searching for the number = %d...\n", pid);

  /* Initialize the mutex lock */
  pthread_mutex_init(&lock, NULL);

  /* Create the searching threads */
  for (started=0; started<NUM_THREADS; started++)
    pthread_create(&threads[started], NULL, search, (void *) (long int) pid);

  /* Wait for (join) all the searching threads */
  for (i=0; i<NUM_THREADS; i++)
    pthread_join(threads[i], NULL);

  printf("It took %d tries to find the number.\n", tries);

  /* Exit the program */
  return 0;
}

Here is the call graph for this function:

void print_it ( void *  arg)

Definition at line 53 of file ex3.c.

{
  int *try = (int *) arg;
  pthread_t tid;

  /* Get the calling thread's ID */
  tid = pthread_self();

  /* Print where the thread was in its search when it was cancelled */
  printf("Thread %lx was canceled on its %d try.\n", tid, *try);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void * search ( void *  arg)

Definition at line 67 of file ex3.c.

{
  int num = (long int) arg;
  int i, j, ntries;
  pthread_t tid;

  /* get the calling thread ID */
  tid = pthread_self();

  /* use the thread ID to set the seed for the random number generator */
  /* Since srand and rand are not thread-safe, serialize with lock */

  /* Try to lock the mutex lock --
     if locked, check to see if the thread has been cancelled
     if not locked then continue */
  while (pthread_mutex_trylock(&lock) == EBUSY)
    pthread_testcancel();

  srand((int)tid);
  i = rand() & 0xFFFFFF;
  pthread_mutex_unlock(&lock);
  ntries = 0;

  /* Set the cancellation parameters --
     - Enable thread cancellation
     - Defer the action of the cancellation */

  pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
  pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);

  while (started < NUM_THREADS)
    sched_yield ();

  /* Push the cleanup routine (print_it) onto the thread
     cleanup stack.  This routine will be called when the
     thread is cancelled.  Also note that the pthread_cleanup_push
     call must have a matching pthread_cleanup_pop call.  The
     push and pop calls MUST be at the same lexical level
     within the code */

  /* Pass address of `ntries' since the current value of `ntries' is not
     the one we want to use in the cleanup function */

  pthread_cleanup_push(print_it, (void *)&ntries);

  /* Loop forever */
  while (1) {
    i = (i + 1) & 0xFFFFFF;
    ntries++;

    /* Does the random number match the target number? */
    if (num == i) {
      /* Try to lock the mutex lock --
         if locked, check to see if the thread has been cancelled
         if not locked then continue */
      while (pthread_mutex_trylock(&lock) == EBUSY)
        pthread_testcancel();

      /* Set the global variable for the number of tries */
      tries = ntries;
      printf("Thread %lx found the number!\n", tid);

      /* Cancel all the other threads */
      for (j=0; j<NUM_THREADS; j++)
        if (threads[j] != tid) pthread_cancel(threads[j]);

      /* Break out of the while loop */
      break;
    }

    /* Every 100 tries check to see if the thread has been cancelled. */
    if (ntries % 100 == 0) {
      pthread_testcancel();
    }
  }

  /* The only way we can get here is when the thread breaks out
     of the while loop.  In this case the thread that makes it here
     has found the number we are looking for and does not need to run
     the thread cleanup function.  This is why the pthread_cleanup_pop
     function is called with a 0 argument; this will pop the cleanup
     function off the stack without executing it */

  pthread_cleanup_pop(0);
  return((void *)0);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 20 of file ex3.c.

volatile int started

Definition at line 22 of file ex3.c.

Definition at line 19 of file ex3.c.

Definition at line 21 of file ex3.c.