Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

passing a local variable to thread. is it possible?

i'm working on gcc , i'm wondering if this is possible:

I have a function (NOTmain but aLocalFn) and I declare a local variable in it. Then I pass this local argument as a thread argument. is it doable? or there is the chance (depending on what is run first) that the aLocalVar will be lost before threadFunction is run and the reference idxPtr will be pointing to senselessness??

int *threadFunction(void *idxPtr){
    int rec_idx=(int) *idxPtr;

    //work in the thread with this variabel rec_idx
}

int aLocalFn(){
   int aLocalVar=returnsRecordIndex();

   pthread_create(&thread_id,&attr_detached,threadFunction, &aLocalVar)!=0)
   return 0;
}   

thank you for your help

like image 390
nass Avatar asked May 21 '12 09:05

nass


People also ask

Can threads access local variables?

But: No, threads do not share real local variables.

Can you pass arguments to a thread?

You can only pass a single argument to the function that you are calling in the new thread.

Are local variables thread safe in Python?

Local variables and parameters are always thread-safe. Instance variables, class variables, and global variables may not be thread-safe (but they might be).

Are local objects thread safe?

Local References All objects are stored in the shared heap. If an object created locally never escapes the method it was created in, it is thread-safe. In fact, you can also pass it on to other methods and objects as long as none of these methods or objects make the passed object available to other threads.


5 Answers

This code is incorrect. The function aLocalFn may return before the thread function starts executing. And so by the time the thread function reads the local variable, the scope of that variable may have ended.

What can confuse matters is that this code may very well appear to work, at least some of the time. However, it is incorrect and you should use heap allocated memory instead.

like image 144
David Heffernan Avatar answered Nov 02 '22 13:11

David Heffernan


your code has a life-time issue with "aLocalVar" if you just want to pass an integer, here is a non-portable way to do it. it does not work on some platforms, but you are not likely to encounter those.

void threadFunction ( void * idxptr ) {
    int rec_idx = (int) idxptr;
    ....
}

int rec_idx = returnsRecordIndex();
pthread_create (&thread1, &attr_detached, (void *) &threadFunction, (void *)rec_idx);
like image 26
pizza Avatar answered Nov 02 '22 13:11

pizza


It's doable, but it's not done in the code in your question. You will have to add a signal variable to indicate when the new thread is done using the variable. Then your outer function can return.

static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t signal = PTHREAD_COND_INITIALIZER;
int done;

int *threadFunction(void *idxPtr){
    int rec_idx=(int) *idxPtr;

    pthread_mutex_lock(&lock);
    done = 1;
    pthread_cond_signal(&signal);
    pthread_mutex_unlock(&lock);

    //work in the thread with this variabel rec_idx
}

int aLocalFn(){
    int aLocalVar=returnsRecordIndex();

    done = 0;
    pthread_create(&thread_id,&attr_detached,threadFunction, &aLocalVar)!=0)
    pthread_mutex_lock(&lock);
    while (!done)
        pthread_cond_wait(&signal, &lock);
    pthread_mutex_unlock(&lock);
    return 0;
}   

Note that this example code is itself not thread safe (if multiple threads call aLocalFn).

This does complicate the code, and locking is expensive. So in most cases you're probably better off storing the data in the heap and letting the new thread or pthread_join code free it.

like image 21
Per Johansson Avatar answered Nov 02 '22 11:11

Per Johansson


@pizza's answer is what I'd do. Another way for you to do it would be to use malloc/free as @David hinted at. I would certainly do this over the wait loop proposed in other answers here.

int *threadFunction(void *idxPtr){
    int rec_idx = *(int *)idxPtr;
    // free up our int buffer
    free(idxPtr);
    ...
}

int aLocalFn(){
    int aLocalVar = returnsRecordIndex();
    // allocate some space for our int
    int *intBuf = (int *)malloc(sizeof(int));
    *intBuf = aLocalVar;
    pthread_create(&thread_id,&attr_detached,threadFunction, intBuf)!=0)
    return 0;
}   
like image 42
Gray Avatar answered Nov 02 '22 13:11

Gray


Whenever you are passing variables to a thread function, it is your job to ensure that the variable remains alive and valid till the thread function is done using it.

In your case aLocalFn() continues to execute simultaneously with the new thread and may even finish execution before the thread, that leaves you with an dangling pointer(pointer pointing to data that may not exist) in thread function since the local variable aLocalVar in the function ceases to exist after function returns.

like image 42
Alok Save Avatar answered Nov 02 '22 12:11

Alok Save