マルチスレッドのプログラミング

スレッドの生成

thr_create(3THR) は、Solaris スレッドライブラリルーチンの中で最も精巧なルーチンの 1 つです。

thr_create(3THR)

thr_create(3THR) は、現在のプロセスに新しい制御スレッドを追加します。(POSIX スレッドについては、「pthread_create(3THR) 」を参照)。

新しいスレッドは保留状態のシグナルは継承しませんが、優先順位とシグナルマスクを継承することに注意してください。


#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(2)MAP_NORESERVE オプションを使って割り当てます。)

start_routine - 新しいスレッドで実行する関数を指定します。start_routine() で指定した関数が終了すると、スレッドはその関数の戻り値を終了状態に設定して終了します (詳細は、「thr_exit(3THR)」を参照) してください。

arg - void で記述される任意のもの。通常は 4 バイト値です。それよりも大きな値は、そのポインタを引数とすることによって間接的に渡さなければなりません。

引数は 1 つしか指定できません。複数の引数を与えるためには、それらを 1 つのものとして (構造体に入れるなどの方法で) コーディングしてください。

flags - 生成されるスレッドの属性を指定します。通常は 0 を指定します。

flags の値は、以下に示すフラグのビット単位の論理和となります。


注 -

明示的な同期によって阻止されなければ、停止していない切り離されたスレッドは、そのスレッドの生成元が thr_create() から復帰する前に終了でき、そのスレッド識別子は別の新しいスレッドに割り当てることができます。


new_thread - NULL 以外を指定すると、new_thread の指すアドレスに新しいスレッドのスレッド識別子が格納されます。この引数が指す記憶領域は、呼び出し側の責任で確保しなければなりません。このスレッド識別子は、呼び出し側のプロセス内でだけ有効です。

スレッド識別子が特に必要でなければ、new_thread に 0 を指定してください。

戻り値

正常終了時は 0 です。それ以外の戻り値は、エラーが発生したことを示します。以下のいずれかの条件が検出されると、thr_create() は失敗し、対応する値を戻します。


EAGAIN

システム制限を超えました。たとえば、生成された LWP が多すぎます。


ENOMEM

新しいスレッドを生成するための十分なメモリーがありません。


EINVAL

stack_base が NULL でなく、しかも stack_sizethr_min_stack() の戻り値より小さな値を指定しました。

スタックの動作

Solaris スレッドでのスタックの動作は、通常は pthread の場合と同じです。スタックの設定と操作の詳細は、「スタックについて」を参照してください。

thr_min_stack() を呼び出すと、スタックの大きさの絶対最小値が得られます。この関数は、NULL 手続きを実行するスレッドに必要なスタック空間の大きさを戻します。実用的なスレッドに必要なスタック空間はもっと大きいので、スタックの大きさを小さくするときは十分注意してください。

独自のスタックを指定する方法は 2 通りあります。1 つは、thr_create() でスタックアドレスを NULL に指定し、スタック空間の割り当てをスレッドライブラリに任せる方法です。スタックの大きさを指定するパラメタには、希望の大きさを指定します。

もう 1 つの方法は、thr_create() でスタックアドレスを指定して、スタックをすべて自分で管理する方法です。この場合は、スタック空間の割り当てだけでなく解放もユーザ自身で行う必要があります。つまり、スレッドの終了時にスタックを処分しなければなりません。

独自のスタックを割り当てる場合は、mprotect(2) を呼び出して、スタックの最後に必ずレッドゾーンを付加してください。