0

pthread を使用する必要がある宿題をほぼ完了しました。私はpthreadsを理解しました。私が残した唯一の問題は、pthread_create() を介してスレッドに複数の引数を渡す方法を理解することです。

スレッドに 2 文字を渡す必要があります。pthread_create() で使用するには、それらを (*void) にキャストする必要があります。それらを渡すことはできますが、関数の *parameter から値を取得する方法がわかりません。

void *my_function(void *parameter) {

    /* ATTEMPT 1 - DOESN'T WORK */
    //char* arguments[2];
    //arguments = (char * [2]) parameter;
    /*Error message: 
    error: ISO C++ forbids casting to an array type char* [2] [-fpermissive]
    error: incompatible types in assignment of char** to char*[2]
    */

    /* ATTEMPT 2 - DOESN'T WORK */
    //char *my_data = (char *)parameter;
    //my_data is blank when I try to use cout to check it's values

    /* What I need to do is get those two chars from the array and print them out as part of this thread function */

    pthread_exit(NULL);
}

int main(int argc, char **argv) {

    char duration = '5'; //in reality, this value is taken from argv but I am leaving that out for brevity

    pthread_t threads[3];

    for(int i=0; i < 3; i++){

         char thread_args[2] = {i, duration};

         //create thread with arguments passed in
         int results = pthread_create(&threads[i], NULL, my_function, (void *) &thread_args);

         //testing for pthread error
         if (results){
             printf("ERROR; return code from pthread_create() is %d\n", results);
             exit(-1);
         }

     }

    /* Wait for all threads to complete */
    for (int j=0; j < num_threads; j++) { // https://computing.llnl.gov/tutorials/pthreads/
        pthread_join(threads[j], NULL);
    }


    /* some information prints here that is unrelated to my problem (the date, time, etc) */

    pthread_exit(NULL);
}

問題なく 1 つの値を渡すことができました。助言がありますか?

私が見つけた最も近い既存の質問はこれでしたが、まだ運がありません: Converting from void* to char ** in C

ありがとうございました!

4

1 に答える 1

1

このループ内で次の点に注意してください。

for(int i=0; i < 3; i++){
    char thread_args[2] = {i, duration};
    int results = pthread_create(&threads[i], NULL, my_function, (void *) 
    ...
}

thread_args自動ストレージ期間を持つローカル配列であり、その有効期間は各反復に関連付けられているため、スレッドがアクセスする前にこれらの引数を格納するメモリが解放される可能性があり、その場合は未定義の動作につながります。

より良いアプローチは、このスレッドにデータを渡すために使用する構造を作成することです。

typedef struct {
    char duration;
    int num;
} ThreadData;

次に、コードは次のようになります。

void *my_function(void *parameter) {
    // retrieve and print the thread data:
    ThreadData* td = (ThreadData*) parameter;
    printf("num = %d, duration = %c\n", td->num, td->duration);
    delete td;
    return NULL;
}

int main(int argc, char **argv) {
    char duration = '5';
    pthread_t threads[3];

    for (int i = 0; i < 3; i++) {
        // create structure that will be passed to thread:
        ThreadData* td = new ThreadData;
        td->duration = duration;
        td->num = i;

        //create thread with arguments passed in:
        int ret = pthread_create(&threads[i], NULL, my_function, (void *) td);

        //testing for pthread error:
        if (ret) {
            printf("ERROR; return code from pthread_create() is %d\n", ret);
            exit(-1);
        }
    }
    // wait for all threads to complete:
    for (int i = 0; i < 3; i++) {
        pthread_join(threads[i], NULL);
    }
    exit(0);
}

また、スレッドの実行を終了するには、スレッドのルーチン内の変数が破棄され、スタックが巻き戻されることが保証されているため、returnよりも使用する方がよいことに注意してください。詳細については、pthread 開始関数の return() と pthread_exit()を参照してください。pthread_exitreturn

于 2013-03-12T00:32:59.453 に答える