将局部变量传递给线程。可能吗?

时间:2012-05-21 09:42:36

标签: c multithreading arguments local-variables

我正在研究gcc, 我想知道这是否可能:

我有一个函数(NOTmain但是aLocalFn),我在其中声明了一个局部变量。然后我将此局部参数作为线程参数传递。它可行吗?或者有机会(取决于先运行的是什么)在运行threadFunction之前aLocalVar会丢失并且引用idxPtr将指向无意义?

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;
}   

谢谢你的帮助

5 个答案:

答案 0 :(得分:6)

此代码不正确。函数aLocalFn可能在线程函数开始执行之前返回。因此,当线程函数读取局部变量时,该变量的范围可能已经结束。

令人困惑的是,这段代码似乎很有效,至少在某些时候。但是,它不正确,您应该使用堆分配的内存。

答案 1 :(得分:4)

这是可行的,但在你的问题的代码中没有完成。您必须添加一个信号变量,以指示何时使用该变量完成新线程。然后你的外部函数可以返回。

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;
}   

请注意,此示例代码本身不是线程安全的(如果多个线程调用aLocalFn)。

这会使代码复杂化,锁定也很昂贵。因此,在大多数情况下,最好将数据存储在堆中,然后让新线程或pthread_join代码释放它。

答案 2 :(得分:3)

您的代码存在“aLocalVar”的终身问题 如果你只想传递一个整数,这是一个不可移植的方法。 它在某些平台上不起作用,但你不太可能遇到这些。

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

int rec_idx = returnsRecordIndex();
pthread_create (&thread1, &attr_detached, (void *) &threadFunction, (void *)rec_idx);

答案 3 :(得分:1)

每当您将变量传递给线程函数时,您的工作就是确保变量保持活动并且有效,直到使用它完成线程函数。

在你的情况下,aLocalFn()继续与新线程同时执行,甚至可能在线程之前完成执行,这会在线程函数中留下悬空指针(指向可能不存在的数据的指针),因为函数返回后,函数中的局部变量aLocalVar不再存在。

答案 4 :(得分:1)

@ pizza的回答是我要做的。另一种方法是使用@David暗示的malloc / free。我肯定会在其他答案中提出的等待循环中这样做。

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;
}