views:

52

answers:

2

Hello,

I have an issue with threads.

I am defining a global variable, a char * that I initialize to NULL, and a mutex.

pthread_mutex_t mutex;
char *minURLTime;
minURLTime = NULL;

Then I initialize my mutex:

pthread_mutex_init(&mutex, NULL);

I then create a new thread:

void *status;
pthread_t t;
pthread_create(&t, NULL, executeThread, (void *) &val);
pthread_join(t, &status);

And inside that function I allocate space for minURLTime using strdup and copy a string from link:

pthread_mutex_lock(&mutex); 
minURLTime = strdup(link);
pthread_mutex_unlock(&mutex);  

As I am using the heap (through strdup, which calls malloc), I do not understand why minURLTime is not NULL until the thread is exited, but then it is NULL.

pthread_exit(NULL);

Once pthread_exit is called, although minURLTime is a global variable that was allocated through strdup (which calls malloc), it appears to be NULL. I don't understand, could anyone please explain me?

Thank you very much,

EDIT:

A little more detail.

From main():

void *status;
pthread_t t;

pthread_create(&t, NULL, executeThread, (void *) &val);
pthread_join(t, &status);

ExecuteThread function:

void *
executeThread( void *val )
{
  executeRequest(*((int *) val));
  if (minURLTime != NULL) {
    pthread_mutex_lock(&mutex); 
    fprintf(stderr, "\nURL AFTER THREAD ( BEFORE EXIT ): %s\n", minURLTime); // Not executed
    pthread_mutex_unlock(&mutex); 
  }
  pthread_exit(NULL);
}

fprintf does not get executed (BEFORE returning pthread_exit).

executeRequest Function:

void
executeRequest( int val )
{
  /* some code */

  pthread_mutex_lock(&mutex); 
  minURLTime = strdup(link);
  pthread_mutex_unlock(&mutex);  

  if (minURLTime != NULL) {
    pthread_mutex_lock(&mutex); 
    fprintf(stderr, "\nURL: %s\n", minURLTime); // This one DOES print
    pthread_mutex_unlock(&mutex); 
  }
}

This may be helpful. It prints inside executeRequest, but not inside executeThread, before the thread exited.

Jary

A: 

You aren't waiting in the main thread for the new thread to complete, so you're seeing the null before the thread gets around to setting something else. Also, since you haven't protected the variable with a lock, or declared it volatile, the compiler might even have optimized out noticing that the thread changed it.

bmargulies
I put a mutex_lock around it, sorry about that. So I need to do a pthread_join I believe? Thank you!
Jary
pthread_join should do it, yes.
bmargulies
It is still not working, I will update my previous code.
Jary
Complete code is probably needed at this point.
bmargulies
The complete code is huge (around 1500 lines). I am not sure which part would be helpful here.
Jary
I have some more useful data, I am editing my first post.
Jary
You have to also hold the mutex around the read ... if you aren't waiting for the thread to complete. Are you sure that pthread_create isn't failing altogether?
bmargulies
No the rest of my code is also executing. You are right, I need a mutex when reading too though, thanks.
Jary
I've updated the code. It seems that the variable is NULL as soon as the function calls return.
Jary
I recommend that you print the value of minURLTime explicitly instead of checking it for NULL. It could shed some light on what's going on. You may find out that the second fprintf is not executed at all, for whatever reason: maybe the thread ends up deadlocked while trying to acquire the mutex, or its output somehow gets lost when the thread or the program is terminated. Hard to say without seeing full code. Also, second the advice to declare the variable volatile.
My apologies, I realize what the problem was, it was something inside executeRequest that was messing up with those variables, I really don't know how it could have overwritten exactly THAT part of memory, but it is fixed. Thank you and sorry!
Jary
A: 

My apologies, I realize what the problem was, it was something inside executeRequest that was messing up with those variables, I really don't know how it could have overwritten exactly THAT part of memory, but it is fixed. Thank you and sorry!

Jary
No need to apologize, man! We're all here to help.
Santiago Lezica