0
#include <pthread.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h>

const int kMaxThreads = 10;

void * threadRoutine(void * threadArg) {
    int myThreadNumber = * ((int * ) threadArg);
    //(int)threadArg
    printf("threadRoutine()=>: this is thread number %d!\n", myThreadNumber);
    int sleepTime = random() % 20;
    sleep(sleepTime);
    printf("threadRoutine()=>: thread[%d] completed after sleeping %d [secs]!\n",
        myThreadNumber, sleepTime);
    pthread_exit((void * ) myThreadNumber);
}

int main(int argc, char * argv[]) {
    pthread_t threads[kMaxThreads];
    printf("main()=>: creating threads...\n");
    for (int jj = 0; jj < kMaxThreads; jj++) {
        if (pthread_create( & threads[jj], NULL, threadRoutine, (void * ) jj) != 0) {
            /* undefined reference to a pthread_create*/
        } else {
            printf("main()=>: created thread[%d]!\n", jj);
        }
    }
    printf("main()=>: waiting for threads to complete...\n");
    for (int jk = 0; jk < kMaxThreads; jk++) {
        void * currentThread;
        if (pthread_join(threads[jk], & currentThread) != 0) {
            /* undefined reference to a pthread_join*/
        } else {
            printf("main()=>: completed thread[%d]!\n", (int) currentThread);
        }
    }
}

スレッドの作成と参加に問題があります。また、参照によってスレッド パラメーターを渡す方法の構文についてもわかりません。コードは、スレッドが作成されたときと、スレッド ルーチンでスレッドがスリープする時間の長さを出力する必要があります。

4

2 に答える 2

0

pthread_create()あなたが投稿したコードは、スレッド関数に渡すことができる単一の引数で「悪いこと」をしています。pthread_create()シングルvoid *を渡すことができます(これは、他の何かからキャストすることによって派生でき、通常は派生します)。あなたの場合、あなたはこれをやっています:

pthread_create(..., (void * ) jj)

これは に格納されている整数値を受け取り、jjそれを として再解釈しvoid *ます。このポインタがスレッド関数に渡されます。厳密に言えば、anintを a として再解釈することvoid *は疑わしいと言えますが、それが PThreads API の設計方法です。

ただし、スレッド関数では、これを行っています。

int myThreadNumber = * ((int * ) threadArg);

これは、渡された を受け取り、それを(aka )void *へのポインターとして再解釈します。これは、ほとんどのプラットフォームで一般的に受け入れられますが、使用法では, または, ...の値を持つ になります。次に、このポインターを逆参照して、を取得しようとします。したがって、ほとんどの最新のシステムでは、ループの最初の繰り返しでヌル ポインターの逆参照が発生します (ただし、NULL ポインターが数値 0 を持つことは保証されていませんが、最近のほとんどのシステム/コンパイラでは一般的に行われます)。関連するシグナルをキャッチして無視しない限り、結果としてプログラムがクラッシュする可能性があります。int(int *)int *01int* ((int *) ...)

スレッド関数で行うべきことは、最初にキャストされたものvoid *正確にキャストすることです。つまり、int myThreadNumber = (int) threadArg. pthread_create(.... (void *) &jj)または、情報を返すことができるようにポインタが本当に必要な場合は、代わりに呼び出すこともできますがint、ここでやろうとしているのはそうではないようで、ポインタをスタックベースのローカル変数に渡します別の意味でダメでしょう。

参照と値によって引数を渡すことができることに関して、あなたが何を期待しているのかわかりません。API には、 を渡す必要があると記載されているvoid *ため、PThreads の人々に API を変更するよう請願したい場合を除き、それを行う必要があります... または独自のものを作成します...

于 2014-10-23T18:27:42.407 に答える