pthread_setcancelstate, pthread_setcanceltype - cancelability state と
cancelability type を設定する
#include <pthread.h>
int pthread_setcancelstate(int state, int *oldstate);
int pthread_setcanceltype(int type, int *oldtype);
-pthread でコンパイルしてリンクする。
pthread_setcancelstate()
は、呼び出したスレッドの
cancelability state に
state
で指定された
値を設定する。変更前のスレッドの
cancelability state は
oldstate
が指すバッファーで返される。
state
引数には以下の値のいずれか一つを指定しなければならない。
- PTHREAD_CANCEL_ENABLE
- スレッドは取り消し可能
(cancelable) である。
これが全ての新しく作成されるスレッドでのデフォルトの
cancelability state
である。これには最初のスレッドも含まれる。
スレッドの cancelability type
により、取り消し可能なスレッドが
取り消し要求にいつ反応するかが決まる。
- PTHREAD_CANCEL_DISABLE
- スレッドは取り消しできない。取り消し要求を受信した際は、
取り消し可能に設定されるまでその要求はブロックされる。
pthread_setcanceltype()
は、呼び出したスレッドの
cancelability type に
type
で指定された値を設定する。
変更前のスレッドの
cancelability type は
oldtype
が指すバッファーで返される。
type
引数には以下の値のいずれか一つを指定しなければならない。
- PTHREAD_CANCEL_DEFERRED
- そのスレッドが次に取り消しポイント
(cancellation point) の関数を
呼び出すまで取り消し要求が遅延される。これが全ての新しく作成される
スレッドでのデフォルトの
cancelability type である。
これには最初のスレッドも含まれる。
- Even with deferred cancellation, a cancellation point in an
asynchronous signal handler may still be acted upon and the effect is as
if it was an asynchronous cancellation.
- PTHREAD_CANCEL_ASYNCHRONOUS
- スレッドはいつでも取り消すことができる
(通常はすぐにキャンセルされるが、
システムがそのことを保証しているわけではない)。
これらの関数により実行される「設定と取得」操作
(set-and-get operation) は、
同じ関数を呼び出したプロセス内の他のスレッドがあっても、
アトミックに行われる。
成功すると、これらの関数は
0 を返す。
エラーの場合、0
以外のエラー番号を返す。
pthread_setcancelstate()
は以下のエラーで失敗する場合がある。
- EINVAL
-
state
に無効な値が指定された。
pthread_setcanceltype()
は以下のエラーで失敗する場合がある。
- EINVAL
-
type
に無効な値が指定された。
この節で使用されている用語の説明については、
attributes(7) を参照。
インターフェース |
属性 |
値 |
pthread_setcancelstate(), pthread_setcanceltype() |
Thread safety |
MT-Safe |
pthread_setcancelstate(), pthread_setcanceltype() |
Async-cancel-safety |
AC-Safe |
POSIX.1-2001, POSIX.1-2008.
スレッドが取り消された場合に何が起こるかの詳細については
pthread_cancel(3) を参照。
取り消し要求により中断されてはならない重要なアクションをスレッドが
実行する場合、短い時間だけ
cancelability
を無効にするのは有用である。
長い時間 cancelability
を無効にしたり、長い時間停止
(block) される
可能性のある操作の前後で
cancelability
を無効にしたりする際には
注意すること。なぜなら、無効にしてしまうと、キャンセル要求に対して
スレッドが応答しない状態になってしまうからである。
cancelability type を
PTHREAD_CANCEL_ASYNCHRONOUS
に設定して役に立つことはめったにない。スレッドは
いつでもキャンセルすることができることになるので、スレッドが安全にリソースの確保
(例えば
malloc(3)
でメモリーを割り当てる)
や
mutex、セマフォ、ロックなどの獲得を行うことができない。アプリケーションは、スレッドがキャンセルされる際に、これらのリソースがどのような状態にあるかを知る術はないので、リソースの確保が安全ではなくなる。つまり、キャンセルが起こったのが、リソースの確保前なのか、確保中なのか、確保後なのかが分からない。さらに、関数呼び出しの最中にキャンセルが発生すると、いくつかの内部データ構造
(例えば、
malloc(3)
関連の関数が管理している未使用ブロックのリンクリスト)
が一貫性のない状態のままになってしまう可能性がある。その結果、クリーンアップハンドラーが役に立たないものになってしまう。
非同期で安全にキャンセルできる関数は
async-cancel-safe functions
と呼ばれる。 POSIX.1-2001 と
POSIX.1-2008
で、非同期で安全にキャンセルできるように求められている関数は
pthread_cancel(3),
pthread_setcancelstate(),
pthread_setcanceltype()
だけである。
一般的には、それ以外のライブラリ関数は、非同期にキャンセルできるスレッドから安全に呼び出すことはできない。
非同期でのキャンセルが有効な数少ない状況としては、純粋に計算だけを行うループに入っているスレッドをキャンセルするといった場面がある。
Linux
のスレッド実装では、
pthread_setcancelstate() の
oldstate
引数に NULL
を指定することを認めている。
NULL
が指定された場合、変更前の
cancelability state
の情報が呼び出し側に返されない。他の多くの実装でも
oldstate 引数に NULL
を指定することを認めているが、
POSIX.1
ではこの点については規定されていない。したがって、移植性が必要なアプリケーションでは常に
oldstate に NULL
以外の値を指定するようにすべきである。
pthread_setcanceltype() の
oldtype
引数についても、全く同じことが言える。
pthread_cancel(3) を参照。
pthread_cancel(3),
pthread_cleanup_push(3),
pthread_testcancel(3),
pthreads(7)
この man ページは Linux
man-pages
プロジェクトのリリース
5.10
の一部である。プロジェクトの説明とバグ報告に関する情報は
https://www.kernel.org/doc/man-pages/
に書かれている。