6

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

ご協力ありがとうございました

4

5 に答える 5

8

このコードは正しくありません。スレッド関数が実行を開始する前に、関数aLocalFnが戻る場合があります。したがって、スレッド関数がローカル変数を読み取るまでに、その変数のスコープは終了している可能性があります。

問題を混乱させる可能性があるのは、このコードが少なくとも一部の時間は機能しているように見える可能性があることです。ただし、これは正しくないため、代わりにヒープに割り当てられたメモリを使用する必要があります。

于 2012-05-21T09:49:40.720 に答える
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したがって、ほとんどの場合、データをヒープに格納し、新しいスレッドまたはコードで解放する方がよいでしょう。

于 2012-05-21T10:13:24.677 に答える
4

整数を渡したいだけの場合、コードには「aLocalVar」に関する生涯の問題があります。これを行うには移植性のない方法があります。一部のプラットフォームでは機能しませんが、それらに遭遇する可能性は低いです。

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

int rec_idx = returnsRecordIndex();
pthread_create (&thread1, &attr_detached, (void *) &threadFunction, (void *)rec_idx);
于 2012-05-21T10:23:43.557 に答える
2

@ピザの答えは私がすることです。@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;
}   
于 2012-05-21T13:13:52.487 に答える
1

変数をスレッド関数に渡すときはいつでも、スレッド関数がその変数を使用し終わるまで変数が生きていて有効であることを保証するのはあなたの仕事です。

あなたの場合、新しいスレッドと同時に実行し続け、スレッドの前に実行を終了することさえあります。関数内のローカル変数が存在しなくなるためaLocalFn()、スレッド関数にダングリング ポインター (存在しない可能性のあるデータを指すポインター) が残ります。aLocalVar関数が戻った後。

于 2012-05-21T09:51:53.190 に答える