Flame of udun
Flame of udun

Reputation: 2237

Can't understand this basic threads behaviour

I am studying about threads and concurrent programming. Tried this basic example from what was provided in class:

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

#define NUM_THREADS 8

void *printGoGators(void *noArg)
{
  printf("Go Gators!\n");
  return NULL;
}

int main(int argc, char *argv[])
{
  pthread_t threads[NUM_THREADS];
  int rc, t;
  for (t = 0; t < NUM_THREADS; t++)
    {
      printf("Creating thread %d\n", t);
      rc = pthread_create(&threads[t],
              NULL,
              printGoGators,
              NULL);
      if(rc)
    {
      printf("ERROR %d", rc);
      exit(-1);
    }
    }
  pthread_exit(NULL);
}

This code produces the following output. :

Creating thread 0
Creating thread 1
Go Gators!
Creating thread 2
Go Gators!
Creating thread 3
Go Gators!
Creating thread 4
Go Gators!
Creating thread 5
Go Gators!
Creating thread 6
Go Gators!
Creating thread 7
Go Gators!
Go Gators!

Why is Go Gators! not printed directly after its corresponding Creating thread # for all threads? Please help!

Upvotes: 0

Views: 89

Answers (2)

user3196144
user3196144

Reputation: 307

After you create a thread it is up to the OS to decide what order threads are executed. You can control it using mutexes and conditions to lock a thread let another thread to run and then unlock it.

Unlike accepted answer, this example uses threads and not just print something in a loop.

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

#define NUM_THREADS 8

pthread_mutex_t myMutex;                // Declere global mutex
pthread_cond_t myCondition;             // Declere global condition


void *printGoGators(void *arg)    {         

  printf("Go Gators! %i\n", *(int*)arg);
  delete (int*) arg;

   pthread_cond_signal(&myCondition);    // Signal that a condition is met

  return NULL;
}

int main(int argc, char *argv[])  {

  pthread_mutex_init(&myMutex, NULL);              // Initialize mutex
  pthread_cond_init (&myCondition, NULL);          // Initialize condition

  pthread_t threads[NUM_THREADS];
  int rc, t;
  for (t = 0; t < NUM_THREADS; t++)    {

        int* n = new int;
        *n = t;

      printf("Creating thread %d\n", t);
      rc = pthread_create(&threads[t],
              NULL,
              printGoGators,
              n);            

      if(rc)   {
      printf("ERROR %d", rc);
      exit(-1);
    }


  pthread_cond_wait(&myCondition, &myMutex);         // waite for condition

    }
  pthread_exit(NULL);
}

result:

Creating thread 0
Go Gators! 0
Creating thread 1
Go Gators! 1
Creating thread 2
Go Gators! 2
Creating thread 3
Go Gators! 3
Creating thread 4
Go Gators! 4
Creating thread 5
Go Gators! 5
Creating thread 6
Go Gators! 6
Creating thread 7
Go Gators! 7

Main thread creation loop: Create a thread and then wait for the condition.

New thread: Print a message then signal that condition is met.

This way you manage the order of execution.

Upvotes: 1

millinon
millinon

Reputation: 1576

If your code looked like this, then the output would be in the order you expect:

for (t = 0; t < NUM_THREADS; t++)
    {
      printf("Creating thread %d\n", t);
      printGoGators(NULL);
    }

So, you're making an assumption that threads will execute in the same order that they are created. However, that assumption is incorrect - threads may execute in any order.

Upvotes: 4

Related Questions