pthread_sigmask - ライブラリコールの説明 - Linux コマンド集 一覧表
名前
pthread_sigmask, pthread_kill, sigwait - スレッド内でのシグナルハンドリング
書式
#include <pthread.h>
#include <signal.h>
int pthread_sigmask(int
how
, const sigset_t *
newmask
, sigset_t *
oldmask
);
int pthread_kill(pthread_t
thread
, int
signo
);
int sigwait(const sigset_t *
set
, int *
sig
);
説明
"pthread_sigmask"
は呼び出しスレッドのシグナルマスクを
引数
"how"
および
"newmask"
で指定されるように変更する。
"oldmask"
が
"NULL"
でないときには、直前のシグナルマスクが
"oldmask"
で指し示される領域に格納される。
引数
"how"
および
"newmask"
の意味は
sigprocmask
(2) の引数の意味と同じである。
"how"
が
"SIG_SETMASK"
のときには、
シグナルマスクが
"newmask"
に設定される。
"how"
が
"SIG_BLOCK"
のときには、
"newmask"
で指定されるシグナルが現時点のシグナルマスクに追加される。
"how"
が
SIG_UNBLOCK
のときには、
"newmask"
で指定されるシグナルが現時点のシグナルマスクから取り除かれる。
シグナルマスクはスレッドごとに設定されることを思い出してほしい。
しかし
sigaction
(2) で設定される
シグナルアクションとシグナルハンドラは、
すべてのスレッドで共通である。
"pthread_kill"
はシグナル番号
"signo"
のシグナルを
スレッド
thread
に送信する。
シグナルは
kill
(2) に書かれているように配送されハンドルされる。
"sigwait"
は
"set"
で指定されるシグナルのうちいずれか 1 つが呼び出しスレッドに
配送されるまで呼び出しスレッドの実行を停止する。
そして受信したシグナルの数を
"sig"
で指し示される領域に格納して返る。
"set"
で指定されるシグナルは
"sigwait"
に入るときにブロックされていなければならず、無視されてはならない。
配送されたシグナルに対するシグナルハンドラが登録されていても、
ハンドラ関数は呼び出され
"ない"
。
取り消し
"sigwait"
は取り消しポイントである。
返り値
成功すると、0 が返る。
失敗の場合、非 0 のエラーコードが返る。
エラー
関数
"pthread_sigmask"
はエラーのとき、次のようなエラーコードを返す:
- "EINVAL"
-
"how"
が
"SIG_SETMASK"
および
"SIG_BLOCK"
、
"SIG_UNBLOCK"
のいずれでもない。
- "EFAULT"
-
"newmask"
または
"oldmask"
が無効なアドレスを指している。
関数 "pthread_kill" はエラーのとき、次のようなエラーコードを返す:
- "EINVAL"
-
"signo"
は有効なシグナル番号でない。
- "ESRCH"
-
スレッド
"thread"
は存在しない (例えば、そのスレッドはすでに終了している) 。
関数 "sigwait" がエラーを返すことはない。
著者
Xavier Leroy <Xavier.Leroy@inria.fr>
関連項目
注意
"sigwait"
が確実に機能するように、
配送を待つシグナルは、呼び出しスレッドだけでなく
すべてのスレッドでブロックされていなければならない。
そうでない場合、POSIX のシグナル配送機構は
シグナルを受信するスレッドが
"sigwait"
を呼び出しているスレッドとなることを保証しない。
これを実現する最もよい方法は、
どのスレッドを生成するよりも前にそれらのシグナルをブロックし、
プログラム中では
"sigwait"
を呼び出す以外、ブロックを解除しないことである。
バグ
LinuxThreads のシグナルハンドリングは POSIX 標準とは大きく異なっている。
POSIX 標準によると、「非同期の」 (外部の) シグナルは
プロセス全体 (すべてのスレッドの集まり) に対して発行され、
その後特定の 1 つのスレッドに配送される。
実際にシグナルを受信するスレッドは
その時点でシグナルをブロックしていないスレッドのいずれかとなる。
LinuxThreads では、
それぞれのスレッドが実際には固有の PID をもつカーネルプロセスであるため、
外部のシグナルは特定の 1 つのスレッドに直接配送される。
例えば、もし別のスレッドが
"sigwait"
を使ってそのシグナルをブロックしても、
そのスレッドが再開されることはない。
"sigwait"
の LinuxThreads の実装では、
"sigwait"
は待ちの期間中、
"set"
に含まれるシグナルに対応するダミーのシグナルハンドラを登録する。
シグナルハンドラはすべてのスレッドで共通であるため、
他のスレッドはこれらのシグナルに対して独自のシグナルハンドラを登録してはならない。
あるいはその代わりに、すべてのスレッドが
これらのシグナルをブロックしなければならない
(このことはとにかく推奨されている -- 注意のセクションを参照のこと) 。