6

POSIX pthread ライブラリを使用して次のコードを作成しました。

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

pthread_t pid1,pid2;

void *test(void *arg)
{
void **end;
printf("\nNew Thread ID: 0x%x\n",(unsigned int)pid2);
pthread_join(pid1,end);
printf("\nNew Thread going to go off\n");
printf("\nNew Thread ID: 0x%x\n",(unsigned int)pid2);
return ((void *)NULL);
}    

int main()
{
pid1 = pthread_self();
pthread_create(&pid2,NULL,test,NULL);
printf("\nMain Thread ID: 0x%x\n",(unsigned int)pid1);
sleep(2);
printf("\nI am going off\n");
pthread_exit(0);
}

コードを実行すると、次の出力が得られました。

メイン スレッド ID: 0xb7880b30
新しいスレッド ID: 0xb787eb70
私は行きます
セグメンテーション違反

私が調べたように、pthread_join を呼び出すスレッド (pid2) は、引数 (pid1) で渡されたスレッドが pthread_exit() を呼び出すまでブロックされます。また、pthread_exit() は、特定のスレッドの実行を停止して、他のすべてのスレッドの実行を継続させるために使用されます。

最後にセグメンテーション違反が発生した理由を知りたいです。

きちんと説明してください。

4

3 に答える 3

9

初期化されていない変数を使用しているためvoid **end;、未定義の動作が発生します。

pthread_join(pid1,end);

代わりにすべきことは次のとおりです。

void *end;
pthread_join(pid1, &end);

つまり、初期化されていないポインタではなく、結果が必要な変数に意味のあるポインタを渡します。

于 2011-05-03T20:04:30.483 に答える
5

end問題は、渡されたポインタがpthread_join()実際にはどこも指していないことだと思います。次のことを試してください。

void *test(void *arg)
{
    void *end;    // <===
    printf("\nNew Thread ID: 0x%x\n",(unsigned int)pid2);
    pthread_join(pid1,&end);  // <===
    printf("\nNew Thread going to go off\n");
    printf("\nNew Thread ID: 0x%x\n",(unsigned int)pid2);
    return ((void *)NULL);
}
于 2011-05-03T20:04:51.017 に答える
1

セグメンテーション違反は単に、OS がコードの実行または読み取り/書き込みを許可していないメモリへのアクセスまたはメモリ内の場所へのジャンプを試みたことを意味します。この場合pthread_join()、OS がメインの親プロセスをクリーンアップし、メインの親プロセスによって使用されたすべてのメモリを再利用したため、生成された子スレッドは呼び出し後に戻ると想定されます (これには実行コードとスタックスペースが含まれます)。ヒープスペースなど)? ...ユーザーランドスレッドがアクセスできるのは間違いなくメモリではないため、OSはセグメンテーション違反をスローします。

于 2011-05-03T19:54:45.380 に答える