Question

Sorry if a question title is confusing. I just wanted to put all the things together. I have a piece of code like:

int newThread(int(*pfunc)())
{
   pthread_t tid;
   pthread_create(&tid, NULL, pfunc, NULL);
   int i = 0;
   while(threads[i] != 0 && i < MAX_NUM_THREADS)
   {
      if ((MAX_NUM_THREADS - 1) == i)
      {
        puts("We've run out of threads' number limit\n");
        return 1;
      }
      ++i;
   } 
   threads[i] = tid;
   pthread_join(tid, NULL);
   return 0;
}

threads[] is a global array. I want to make this function reentrant, but this means I shouldn't use global variables as far as I understand. I guess that's because values of global variables can be unpredictable at a certain time. But in my case the array seems to be quite predictable.

  1. Is it ok, if I lock array with a mutex to make this function reentrant?
  2. If yes, then how do I do it right? Just lock the first element before using it and unlock after? or is it better to lock/unlock every element while accessing it?
  3. Is this even possible to make this function reentrant?
Was it helpful?

Solution

To say a function is reentrant, it should only rely on local variables to be simultaneously called by two (or more threads) and return correct results.

If the function rely on some shared data, (we can't really made it reentrant), we can make it thread-safe to be called simultaneously by two (or more) threads if all access to the shared data is serialized.

To make your function thread-safe, you should lock the loop and the insertion into threads[]. If you lock only the loop part, somebody could modify the content of threads between the end of the loop and the affectation at rank i.

pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER;

int newThread(int(*pfunc)())
{
   pthread_t tid;
   pthread_create(&tid, NULL, pfunc, NULL);
   int i = 0;
   pthread_mutex_lock(&mymutex);          // take the lock
   while(threads[i] != 0 && i < MAX_NUM_THREADS)
   {
      if ((MAX_NUM_THREADS - 1) == i)
      {
        puts("We've run out of threads' number limit\n");
        pthread_mutex_unlock(&mymutex);   // don't forget to release the lock here too :)
        return 1;
      }
      ++i;
   } 
   threads[i] = tid;
   pthread_mutex_unlock(&mymutex);        // release the lock
   pthread_join(tid, NULL);
   return 0;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top