2016-06-16 16 views
3

メイン関数から別の子スレッドBを生成するスレッドAを作成しています。pthread_attr_setstacksize()を使用してスレッドAとBにスタックサイズを明示的に割り当てる必要があります。要件ごとに子スレッドのスタック領域

は、親スレッドAのスタックサイズは、子スレッドBよりも小さい

私は混乱していますその子スレッドのスタックは親スレッドやスタックのスタック空間から割り当てられている場合親スレッドと子スレッドのスペースは全く異なります。

誰でもお手伝いできますか?

+6

2つのスレッド/プロセスのスタックは全く異なります。それらのいずれも別のものから割り当てられません。 – GMichael

+0

@Michael:OPは明らかにLinux上にあるので、clone()を使用して親スタック内のアドレスに子スタックを設定することができます。 – EOF

+2

@EOF 'man clone()'は次のように言っています: '子プロセスと呼び出しプロセスがメモリを共有するため、子プロセスが呼び出しプロセスと同じスタック内で実行することはできません。したがって、呼び出しプロセスは、子スタックのメモリ空間を設定し、この空間へのポインタをclone()に渡す必要があります。あなたは常にルールを意図的に破ることができます。しかし、それは 'clone()'開発者があなたが期待するものではありません。 – GMichael

答えて

2

pthread_attr_setstacksize()を使用してスレッドAとBにスタックサイズを明示的に割り当てる必要があります。

だから、あなたはそう:

pthread_attr_t attrs; 
    pthread_t  A, B; 
    void   *A_retval, *B_retval; 
    int    result; 

    result = pthread_attr_init(&attrs); 
    if (result) { 
     fprintf(stderr, "Cannot initialize thread attributes: %s.\n", strerror(result)); 
     exit(EXIT_FAILURE); 
    } 

    result = pthread_attr_setstacksize(&attrs, A_STACK_SIZE); 
    if (result) { 
     fprintf(stderr, "Cannot set stack size %zu for thread A: %s.\n", (size_t)A_STACK_SIZE, strerror(result)); 
     exit(EXIT_FAILURE); 
    } 

    result = pthread_create(&A, &attrs, A_FUNCTION, NULL); 
    if (result) { 
     fprintf(stderr, "Cannot create thread A: %s.\n", strerror(result)); 
     exit(EXIT_FAILURE); 
    } 

    result = pthread_attr_setstacksize(&attrs, B_STACK_SIZE); 
    if (result) { 
     fprintf(stderr, "Cannot set stack size %zu for thread B: %s.\n", (size_t)A_STACK_SIZE, strerror(result)); 
     exit(EXIT_FAILURE); 
    } 

    result = pthread_create(&B, &attrs, B_FUNCTION, NULL); 
    if (result) { 
     fprintf(stderr, "Cannot create thread A: %s.\n", strerror(result)); 
     exit(EXIT_FAILURE); 
    } 

    pthread_attr_destroy(&attrs); 

    /* TODO: Perhaps this thread also does something? */ 

    /* Wait for A and B to exit. */ 

    result = pthread_join(A, &A_retval); 
    if (result) 
     fprintf(stderr, "Warning: Thread A: %s.\n", strerror(result)); 

    result = pthread_join(B, &B_retval); 
    if (result) 
     fprintf(stderr, "Warning: Thread B: %s.\n", strerror(result)); 
要件ごとに

は、親スレッドAのスタックサイズは、念の子スレッドB.

よりも小さくなっていますサイズはページサイズの倍数(sysconf(_SC_PAGESIZE))、少なくともPTHREAD_STACK_MINです。

親スレッドまたは子スレッドはありません。彼らはすべて同じプロセスに属するすべての「兄弟」です。プロセスが開始されたときの唯一のスレッドである「メインスレッド」がありますが、それは決して特別なものではありません。それはmain()からその名前を得ます、それはその機能の実行を開始するスレッドです。どちらのスレッドが他のスレッドを作成したかは関係ありません。

一部のコードでスレッド間に親子関係がある場合は、スレッドの実際の関係ではなくコードのロジックを反映するために使用されます。 「親」「子」「新しく​​作成されたスレッド」「新しく​​作成されたスレッドを作成したスレッド」のためだけの簡単な速記です。

プロセスは実際の親子関係を持っています - 例えば、親だけがその子プロセスを享受することができます - しかし、すべてのスレッドはLinuxのプロセス内の兄弟です:任意のスレッドは同じスレッド内で他のスレッドを結合/プロセス。

親スレッドのスタックスペースから子スレッドのスタックを割り当てたり、親スレッドと子スレッドのスタックスペースが完全に異なる場合は混乱します。

いいえ、各スレッドにはそれぞれ独自のスタックがあります。この新しいスタックは、ほとんどの場合、属性が指定されている場合は目的のスタックサイズを使用し、属性が指定されていない場合はデフォルトのスタックサイズ(巨大な数メガバイト)を使用して、自動的にpthread_create()呼び出しによって自動的に割り当てられ、準備されます。

(その属性セットを使用して作成された次のスレッドに明示的なスタックを設定するための呼び出しがあります)実際には奇妙なアプリケーションには特定のスタック配置が必要な場合があります。十分に大きく整列されている必要があります。それを例えばmmap()を使用して、それを自分で割り当てることが可能であるが、それは間違いなくあなたがこれまでに行うために、必要がある、またはたくなければならないものではありません。)


で使用されるメモリ領域を見るのは興味深いまたは有益でありプログラム自体、または特定のプロセスによって実行されます。

Linuxでは、プログラムは/proc/self/maps pseudofile(ディスク上の実際のファイルではありませんが、オープンして読むときにカーネルがその場で生成するファイルのようなエンティティです)を開いて読むことができます。プロセスID PIDに対応する任意の/proc/PID/maps

各行の最初の2つの16進数はアドレス範囲を表し、スタックは[stack]とマークされます。

/proc pseudofilesystemのファイルの詳細については、man 5 procを参照してください。

関連する問題