#include <pthread.h> int pthread_cancel(pthread_t thread); -pthread でコンパイルしてリンクする。
あるスレッドの cancelability state は pthread_setcancelstate(3) で 設定され、enabled と disabled のいずれとなる (enabled が新しい スレッドのデフォルト値である)。スレッドがキャンセルを無効にしていた場合、 キャンセル要求はそのスレッドがキャンセルを有効にするまでキューに入れら れたままになる。スレッドがキャンセルを有効にしていた場合、 cancelability type によって、いつキャンセルが発生するかが決まる。
スレッドのキャンセル種別 (cancelability type) は pthread_setcanceltype(3) で設定され、asynchronous か deferred のいずれかとなる(deferred が新しいスレッドのデフォルト値である)。 非同期キャンセル (asynchronous cancelability) は、そのスレッドはいつで もキャンセルされることを意味する (通常はすぐにキャンセルされるが、 システムがそのことを保証しているわけではない)。遅延キャンセル (deferred cancelability) では、そのスレッドが 取り消しポイント (cancellation point) となっている関数を次に呼び出すまでキャンセルが 遅延される。取り消しポイントに設定されていたり設定 したりできる関数のリストは pthreads(7) に記載している。
キャンセル要求が実行されると、 thread では以下のステップが (この順序で) 行われる。
上記のステップは pthread_cancel() の呼び出しとは非同期に行われる。 pthread_cancel() の返却ステータスは単にキャンセル要求が正常に キューに入れられたかどうかを呼び出し元に示すだけのものである。
キャンセルされたスレッドが終了された後に、 pthread_join(3) でそのスレッドを join すると、 そのスレッドの終了ステータスとして PTHREAD_CANCELED が得られる。 (スレッドの join はキャンセルが完了したかを知る唯一の方法である)
インターフェース | 属性 | 値 |
pthread_cancel() | Thread safety | MT-Safe |
$ ./a.out thread_func(): started; cancellation disabled main(): sending cancellation request thread_func(): about to enable cancellation main(): thread was canceled
#define handle_error_en(en, msg) \
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
static void *
thread_func(void *ignored_argument)
{
int s;
/* Disable cancellation for a while, so that we don't
immediately react to a cancellation request */
s = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
if (s != 0)
handle_error_en(s, "pthread_setcancelstate");
printf("thread_func(): started; cancellation disabled\n");
sleep(5);
printf("thread_func(): about to enable cancellation\n");
s = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
if (s != 0)
handle_error_en(s, "pthread_setcancelstate");
/* sleep() is a cancellation point */
sleep(1000); /* Should get canceled while we sleep */
/* Should never get here */
printf("thread_func(): not canceled!\n");
return NULL;
}
int
main(void)
{
pthread_t thr;
void *res;
int s;
/* Start a thread and then send it a cancellation request */
s = pthread_create(&thr, NULL, &thread_func, NULL);
if (s != 0)
handle_error_en(s, "pthread_create");
sleep(2); /* Give thread a chance to get started */
printf("main(): sending cancellation request\n");
s = pthread_cancel(thr);
if (s != 0)
handle_error_en(s, "pthread_cancel");
/* Join with thread to see what its exit status was */
s = pthread_join(thr, &res);
if (s != 0)
handle_error_en(s, "pthread_join");
if (res == PTHREAD_CANCELED)
printf("main(): thread was canceled\n");
else
printf("main(): thread wasn't canceled (shouldn't happen!)\n");
exit(EXIT_SUCCESS);
}