【问题标题】:passing a local variable to thread. is it possible?将局部变量传递给线程。可能吗?
【发布时间】:2012-05-21 09:42:35
【问题描述】:

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

我有一个函数(不是main,而是aLocalFn),我在其中声明了一个局部变量。然后我将此本地参数作为线程参数传递。可行吗?或者有可能(取决于首先运行的内容)aLocalVar 在 threadFunction 运行之前会丢失,并且引用 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;
}   

感谢您的帮助

【问题讨论】:

    标签: c multithreading arguments local-variables


    【解决方案1】:

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

    令人困惑的是,这段代码可能看起来很有效,至少在某些时候是这样。但是,这是不正确的,您应该改用堆分配的内存。

    【讨论】:

    • 只是想确认一下:如果我将代码更改为pthread_create(&thread_id,NULL,threadFunction, &aLocalVar)pthread_join somwhere 在pthread_create 之后,可以吗?
    【解决方案2】:

    您的代码存在与“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】:

      @pizza 的回答是我会做的。你这样做的另一种方法是使用 malloc/free 正如@David 暗示的那样。我当然会在此处其他答案中提出的等待循环中执行此操作。

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

      【讨论】:

        【解决方案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 代码释放它。

        【讨论】:

        • 是的,这确实可以完成这项工作,但它肯定不是一个好的解决方案。我相信你不会在堆分配上推荐这个。
        • 我尽量不做超出问题所述的假设。在aLocalFn 是回调并且数据返回时会自动释放的情况下,我需要类似的代码。对于一个简单的int,这并不是一个很好的解决方案,不。
        • +1 表示“不同”的答案。但是,我也不同意这是一个好的解决方案,因为它需要不必要地创建条件变量并让创建者线程资源等待创建完成。
        • 如果您知道代码只会生成 1 个 threadFunction 实例,这可能是一个可接受的解决方案。
        【解决方案5】:

        每当您将变量传递给线程函数时,您的工作就是确保变量在线程函数完成使用之前保持活动和有效。

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

        【讨论】:

          猜你喜欢
          • 2015-03-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-12-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多