2

私は今スレッドについて学んでいます。スレッドに変数を渡すことができるかどうか疑問に思っています。私の課題は、スレッドを作成し、各スレッドに番号 (必要に応じて名前) を割り当て、100 ミリ秒ごとに番号を出力することです。私の現在のプログラムは以下の通りです:

#define PCHECK(sts,msg) if((sts)!=0){printf("error : %s\n",msg); exit(EXIT_FAILURE)}
#define NB_THREAD 5

void* do_nothing(void* data)
{
    int i;

    //printf("creation thread %d",(int)data);
    while(1)
    {
        usleep(100000);
    printf("thread number : %d \n",data);
    }
    i = 0;
    pthread_exit(NULL);   
    //exit(EXIT_SUCCESS);
}

int main(int argc, char *argv[])
{
    int pid, j, status;
    pthread_t thread;
    int * res;
    int stat;

    for (j = 0; j < NB_THREAD; j++)
    {
        stat = pthread_create(&thread, NULL, do_nothing, (void *) j );
        if (stat !=0)
        {
            perror ("pthread_create()");
        }
    }
    for (j = 0; j < NB_THREAD; j++)
    {
        pthread_join(thread, (void **) &res );
    }



    return EXIT_SUCCESS;
}

今のところ、表示される数字は 0 (データの値) だけです。誰かが私がどこで間違っていたのか指摘できますか?ありがとう:)

4

2 に答える 2

2

pthreads に引数を渡す方法の良い例を次に示します。

[1] https://computing.llnl.gov/tutorials/pthreads/#PassingArguments

于 2012-05-19T07:25:15.390 に答える
1

あなたの問題は、32 ビット型を使用する 64 ビット システムでこれを実行している可能性があると思われますint。これdataは 64 ビットvoid*タイプですが、スレッド関数では 32 ビットとして出力していますint

// example assumes that this thread instance was started by
//   pthread_create(&thread, NULL, do_nothing, (void *) j ) when
//   j == 1

printf("thread number : %d \n",data);
                         ^       ^
                         |       +--------  passing a 64-bit pointer 0x00000000.00000001
                         |
                         +----------------  treats the pointer argument as a 32-bit int and
                                            happens to only see the all-zero 32-bits

を次のように変更すると、期待する出力が得られると思いますprintf()

printf("thread number : %d \n", (int) data);

原則として、スレッド関数を作成するときは、スレッド関数に渡されたデータ項目を実際に渡された型に変換することをスレッド関数の最初のアクションにすることをお勧めしますpthread_create()

void* do_nothing(void* data)
{
    int id = (int) data; // `pthread_create()` was passed an `int`
                         //    `data` is not used again after this point

    // ...
}

その他いくつかのポイント

  • データへの実際のポインターをスレッド関数に渡す場合は、各スレッドが独自の個別のコピーを取得するようにしてください (データが各スレッドで同じインスタンスであると想定されている場合を除きますが、これは可能ですが一般的ではありません)。

  • 複数のスレッドをスピンアップしている場合は、後でそれらに参加できるように、pthread_t返された各オブジェクトを(おそらく配列で)保持する必要があります。または、オブジェクトを再利用する前に/を呼び出して、システムがすべてをクリーンアップできるようにする必要があります。スレッドの実行が終了したときにそのスレッドに割り当てられたリソース。投稿された例では、スレッドが永久に (または何かがプロセスを強制終了するまで) 実行されるため、それほど重要ではない可能性があります。通話が正常に完了することはありません。pthread_create()pthread_join()pthread_detach()pthread_tpthread_join()

    ただし、次のコードは変更すると壊れる運命にあるため、しばらくするとスレッド関数が停止します。

    for (j = 0; j < NB_THREAD; j++)
    {
        pthread_join(thread, (void **) &res );
    }
    

    thread最後に作成されたスレッドの しかないためpthread_t、正常に参加すると、それ以上使用することはできません。次のループ反復では、既に結合されていて無効になっているスレッドに結合しようとします。

于 2012-05-19T17:19:33.133 に答える