PTHREAD_CANCEL(3)

NAME
pthread_cancel, pthread_setcancelstate, pthread_setcanceltype, pthread_testcancel - スレッドの取り消し

書式
#include <pthread.h> int pthread_cancel(pthread_t thread); int pthread_setcancelstate(int state, int *oldstate); int pthread_setcanceltype(int type, int *oldtype); void pthread_testcancel(void);

説明
取り消しは、あるスレッドが他のスレッドの実行を終了させることを可能 にするメカニズムである。より正確には、スレッドは他のスレッドに対して 取消要求を送ることができる。設定次第で、目標のスレッドは、要求を無視 したり、直ちに実現したり、ある取り消しポイントに至るまでその要求の実行 を延期したりできる。 スレッドが最終的に取り消し要求を実現する際には、それはあたかも pthread_exit(PTHREAD_CANCELED) がその時点で呼び出されたかのように振舞う。すなわち、全てのクリーン アップハンドラが逆順に実行され、スレッド固有データの終了処理関数が 呼び出され、最後にスレッドは、返り値 PTHREAD_CANCEL で実行を停止する。詳しくは pthread_exit(3) を見よ。 pthread_cancel は thread 引数で指定されたスレッドに対して、取り消し要求を送る。 pthread_setcancelstate は、これを呼び出すスレッドの取り消し状態を変更する。 すなわち、取り消し要求を受け入れるか否かを変更する。 state 引数は新たな取り消し状態である。これは取り消しを可能にする PTHREAD_CANCEL_ENABLE もしくは、取り消しを不可能にする(取り消し要求を無視する) PTHREAD_CANCEL_DISABLE のいずれかである。 oldstate が NULL でなければ、以前の取り消し状態が oldstate が指す場所に格納され、従って、後で別の pthread_setcancelstate の呼び出しにより、回復することができる。 pthread_setcanceltype は、これを呼び出すスレッドの取り消し要求に対する反応の型を変更する。 これは、非同期(即時)または遅延のいずれかである。 type 引数は、新たな取り消し方であり、取り消し要求が届くと直ちに呼び出し スレッドを取り消す PTHREAD_CANCEL_ASYNCHRONOUS か、取り消し要求を次の取り消しポイントまで留保する PTHREAD_CANCEL_DEFERRED かのいずれかである。 oldtype が NULL でなければ、以前の取り消し型が oldtype の指す場所に格納され、従って、後から別の pthread_setcanceltype の呼び出しによって回復することが可能である。 スレッドは常に pthread_create(3) によって、取り消し可能かつ遅延で作成される。 すなわち、初期の取り消し状態は PTHREAD_CANCEL_ENABLE であり、初期の型は PTHREAD_CANCEL_DEFERRED である。 取り消しポイントとは、保留中の取り消し要求に対するテストが行われ、 実際に要求があれば取り消しが実行される点である。以下の POSIX スレッド 関数は取り消しポイントである: pthread_join(3)
pthread_cond_wait(3)
pthread_cond_timedwait(3)
pthread_testcancel(3)
sem_wait(3)
sigwait(3) これ以外の全ての POSIX スレッド関数は取り消しポイントではないことが保証 されている。すなわち、それらは遅延取り消しモードで決して取り消しを 実現することはない。 pthread_testcancel は保留中の取り消し要求を調べ、それを実現するだけである。その目的は、 他に取り消しポイントとなる関数を呼び出すことのない、長い連続した コードの中に、明示的に取り消しのチェックを導入することである。

返り値
pthread_cancel、 pthread_setcancelstate および pthread_setcanceltype は成功すると 0 を返し、エラーならば、非ゼロのエラーコードを返す。

エラー
pthread_cancel はエラーの際に次のエラーコードを返す:

    ESRCH
        thread で指定されたものに対応するスレッドが存在しない。 ID.
pthread_setcancelstate はエラーの際に次のエラーコードを返す:

    EINVAL
        state が PTHREAD_CANCEL_ENABLE でも PTHREAD_CANCEL_DISABLE でもない。
pthread_setcanceltype はエラーの際に次のエラーコードを返す:

    EINVAL
        type 引数が PTHREAD_CANCEL_DEFERRED でも PTHREAD_CANCEL_ASYNCHRONOUS でもない。

著者
Xavier Leroy <Xavier.Leroy@inria.fr>

関連項目
pthread_exit(3), pthread_cleanup_push(3), pthread_cleanup_pop(3).

バグ
POSIX は一連のシステムコール(基本的には read(2), write(2), wait(2), 等のようなブロックの可能性のある全ての関数)とそれらのシステムコール を呼ぶようなライブラリ関数(例えば fprintf(3)) が取り消しポイントであると規定している。 LinuxThreads はこれを実装する には、まだ十分に C ライブラリと統合されていると言えず、 従っていかなる C ライブラリの関数も取り消しポイントではない。 少なくとも、システムコールに対してはこれを回避する方法がある。 取り消し要求は、目標スレッドにシグナルを送ることによって送信される。 このシグナルはブロックしているシステムコール全てに対して割込みを掛け、 それらは直ちに EINTR で戻る。よって、例えば read システムコールを呼んでいる間に取り消しをチェックするには、次のように すれば良い:

    pthread_testcancel();
    retcode = read(fd, buffer, length);
    pthread_testcancel();

[訳注] 上の記述は glibc2 を用いたシステムでは正しくない。以下は glib-2.1.2 の info ファイルからの引用である。 取り消しポイントとは、保留中の取り消し要求に対するテストが行われ、 実際に要求があれば取り消しが実行される点である。POSIX スレッド関数 のうち、`pthread_join', `pthread_cond_wait', `pthread_cond_timed_wait', `pthread_testcancel', `sem_wait' 及び `sigwait' は取り消しポイント である。 これに加えて、以下のシステムコールは取り消しポイントである:
 accept open sendmsg
 close pause sendto
 connect read system
 fcntl recv tcdrain
 fsync recvfrom wait
 lseek recvmsg waitpid
 msync send write
 nanosleep これらの関数を呼び出す可能性のある printf() などのライブラリ関数も 取り消しポイントになる場合がある。