thr_create() は、現在のプロセスに新しい制御スレッドを追加します。
新しいスレッドは保留状態のシグナルは継承しませんが、優先順位とシグナルマスクを継承することに注意してください。
#include <thread.h> int thr_create(void *stack_base, size_t stack_size, void *(*start_routine) (void *), void *arg, long flags, thread_t *new_thread); size_t thr_min_stack(void);
stack_base - 新しいスレッドが使用するスタックのアドレスを指定します。NULL を指定すると、新しいスレッドに stack_size バイト以上の大きさをもつスタックが割り当てられます。
stack_size - 新しいスレッドが使用するスタックのバイト数を指定します。0 を指定するとデフォルト値が使用されます。通常は 0 を指定してください。それ以外の値を指定する場合は、thr_min_stack() で戻された値よりも大きな値を指定してください。
通常は、スレッドのためのスタック空間を割り当てる必要はありません。スレッドライブラリが、各スレッドのスタック用に 1M バイトの仮想記憶をスワップ空間の予約なしで割り当てます。(スレッドライブラリは、mmap() の MAP_NORESERVE オプションを使って割り当てます。)
start_routine - 新しいスレッドで実行する関数を指定します。start_routine() で指定した関数が終了すると、スレッドはその関数の戻り値を終了状態に設定して終了します (詳細は、「thr_exit(3T)」を参照) してください。
arg - void で記述される任意のもの。通常は 4 バイト値です。それよりも大きな値は、そのポインタを引数とすることによって間接的に渡さなければなりません。
引数は 1 つしか指定できません。複数の引数を与えるためには、それらを 1 つのものとして (構造体に入れるなどの方法で) コーディングしてください。
flags - 生成されるスレッドの属性を指定します。通常は 0 を指定します。
flags の値は、以下に示すフラグのビット単位の論理和となります。
THR_SUSPENDED - 新しいスレッドを停止させます。thr_continue() でスレッドを再開するまで start_routine は実行されません。このフラグは、スレッドを実行する前に優先順位の変更などを行いたいときに使用します。切り離されたスレッドの終了は無視されます。
THR_DETACHED - 新しいスレッドを切り離します。その結果、このスレッドのスレッド識別子やその他の資源が、スレッド終了後ただちに再利用できるようになります。このフラグは、スレッドの終了を待つ必要がないときに設定してください。
明示的な同期によって阻止されなければ、停止していない切り離されたスレッドは、そのスレッドの生成元が thr_create() から復帰する前に終了でき、そのスレッド識別子は別の新しいスレッドに割り当てることができます。
THR_NEW_LWP - 非結合スレッドの並行度を 1 だけ増やします。この効果は、thr_setconcurrency(3T) で並行度を 1 だけ増やす場合と似ていますが、thr_setconcurrency() 関数で設定される並行度には影響しません。通常、THR_NEW_LWP を指定すると、非結合スレッドを実行する LWP プールに新しい LWP が 1 つ追加されます。
THR_BOUND と THR_NEW_LWP の両方を指定すると、通常は 2 つの LWP が生成されます。1 つは結合スレッドのための LWP で、もう 1 つは非結合スレッドを実行する LWP プールに追加される LWP です。
THR_DAEMON - 新しいスレッドをデーモンにします。デーモンでないスレッドがすべて終了すると、プロセスは終了します。デーモンスレッドは、プロセスの終了状態に影響を与えず、また終了するスレッド数にも含まれません。
プロセスの終了には、次の 2 通りの方法があります。1 つは exit() を呼び出す方法です。もう 1 つは、プロセス内のスレッドのうち THR_DAEMON フラグを指定せずに生成されたすべてのスレッドが thr_exit(3T) を呼び出す方法です。アプリケーションまたはそれが呼び出すライブラリでは、終了判断の際に無視される (数えられない) ようなスレッドを生成できます。THR_DAEMON フラグは、プロセスの終了条件に関係しないスレッドを生成するときに指定します。
new_thread - NULL 以外を指定すると、new_thread の指すアドレスに新しいスレッドのスレッド識別子が格納されます。この引数が指す記憶領域は、呼び出し側の責任で確保しなければなりません。このスレッド識別子は、呼び出し側のプロセス内でだけ有効です。
スレッド識別子が特に必要でなければ、new_thread に 0 を指定してください。
正常終了時は 0 です。それ以外の戻り値は、エラーが発生したことを示します。以下のいずれかの条件が検出されると、thr_create() は失敗し、対応する値を戻します。
Solaris スレッドでのスタックの動作は、通常は pthread の場合と同じです。スタックの設定と操作の詳細は、「スタックについて」を参照してください。
thr_min_stack() を呼び出すと、スタックの大きさの絶対最小値が得られます。この関数は、NULL 手続きを実行するスレッドに必要なスタック空間の大きさを戻します。実用的なスレッドに必要なスタック空間はもっと大きいので、スタックの大きさを小さくするときは十分注意してください。
独自のスタックを指定する方法は 2 通りあります。1 つは、thr_create() でスタックアドレスを NULL に指定し、スタック空間の割り当てをスレッドライブラリに任せる方法です。スタックの大きさを指定するパラメタには、希望の大きさを指定します。
もう 1 つの方法は、thr_create() でスタックアドレスを指定して、スタックをすべて自分で管理する方法です。この場合は、スタック空間の割り当てだけでなく解放もユーザ自身で行う必要があります。つまり、スレッドの終了時にスタックを処分しなければなりません。
独自のスタックを割り当てる場合は、mprotect(2) を呼び出して、スタックの最後に必ずレッドゾーンを付加してください。