pthread_cleanup_push - ライブラリコールの説明 - Linux コマンド集 一覧表
- 名前
- 書式
- 説明
- 返り値
- エラー
- 著者
- 関連項目
- 例
名前
pthread_cleanup_push, pthread_cleanup_pop, pthread_cleanup_push_defer_np, pthread_cleanup_pop_restore_np
- クリーンアップハンドラを登録および削除する
書式
#include <pthread.h>
void pthread_cleanup_push(void (*
routine
) (void *), void *
arg
);
void pthread_cleanup_pop(int
execute
);
void pthread_cleanup_push_defer_np(void (*
routine
) (void *), void *
arg
);
void pthread_cleanup_pop_restore_np(int
execute
);
説明
クリーンアップハンドラは、
pthread_exit
(3) が呼び出されたり、取り消しされたりして
スレッドが終了するときに呼び出される関数である。
クリーンアップハンドラは
スタック風の規則にならって登録および削除される。
クリーンアップハンドラの目的は、
スレッドが終了するときに保持しているかもしれない資源を
解放することである。
殊に、スレッドがロック中の mutex を保持したまま
終了したり取り消しされたりすると、
その mutex は永久にロックされたままで、
ほかのスレッドが正常に実行できなくなってしまう。
このことを防ぐ最もよい方法は、
mutex をロックする直前に、
mutex のロックを解除するための
クリーンアップハンドラを登録することである。
同じように、クリーンアップハンドラは
スレッドの終了時に
malloc
(3) で確保されたメモリブロックを解放したり
ファイルディスクリプターをクローズしたりするのに使用できる。
"pthread_cleanup_push"
は関数
"routine"
を引数
"arg"
とともにクリーンアップハンドラとして登録する。
この時点から
対応する
"pthread_cleanup_pop"
までの間、
そのスレッドが
pthread_exit
(3) または取り消しによって終了する時に、
関数
"routine"
が引数
"arg"
をともなって呼び出されるようになる。
終了する時点で複数のクリーンアップハンドラが有効になっている場合は、
クリーンアップハンドラは LIFO 順に呼び出される:
すなわち、最後に登録されたハンドラが最初に呼び出される。
"pthread_cleanup_pop"
は、最後に登録されたクリーンアップハンドラを削除する。
引数
"execute"
が 0 でない場合、
"pthread_cleanup_pop"
はハンドラを実行する。
すなわち、
関数
"routine"
を引数
"arg"
をともなって呼び出す。
引数
"execute"
が 0 の場合は、ハンドラが削除されるだけで、実行されることはない。
対応する
"pthread_cleanup_push"
と
"pthread_cleanup_pop"
の対は、同じ関数内の、
同じブロック階層になければならない。
実際、
"pthread_cleanup_push"
と
"pthread_cleanup_pop"
はマクロであり、
"pthread_cleanup_push"
のマクロ展開には
開き括弧
"{"
が含まれていて、それに対応する
閉じ括弧
"}"
は、対応する
"pthread_cleanup_pop"
のマクロ展開に含まれている。
"pthread_cleanup_push_defer_np"
は、
"pthread_cleanup_push"
と
pthread_setcanceltype
(3)を組み合わせた、ポータブルでない拡張である。
"pthread_cleanup_push"
とまったく同じようにクリーンアップハンドラを登録するが、
同時にその時点の取り消し型を保存し、
取り消し型を遅延 (deferred) に変更する。
これによって、
スレッドの取り消し型が非同期 (asynchronous) であっても
クリーンアップ機構が有効になることが保証される。
"pthread_cleanup_pop_restore_np"
は
"pthread_cleanup_push_defer_np"
によって登録されたはクリーンアップハンドラを削除し、
取り消し型を
"pthread_cleanup_push_defer_np"
が呼び出された時点の値に戻す。
"pthread_cleanup_push_defer_np"
と
"pthread_cleanup_pop_restore_np"
は対になっていなければならず、
ともに同じブロック階層になければならない。
pthread_cleanup_push_defer_np(routine, arg);
pthread_cleanup_pop_defer_np(execute);
のような流れは機能的に次のものと同等 (だがよりコンパクトでより効率的) である。
{ int oldtype;
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
pthread_cleanup_push(routine, arg);
...
pthread_cleanup_pop(execute);
pthread_setcanceltype(oldtype, NULL);
}
返り値
エラー
著者
Xavier Leroy <Xavier.Leroy@inria.fr>
関連項目
例
次の例は、 mutex
"mut"
をロック中にスレッドが取り消しされたら
ロックを解除するように、
mutex
"mut"
をロックする方法である:
pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut);
pthread_mutex_lock(&mut);
/* 何かをする */
pthread_mutex_unlock(&mut);
pthread_cleanup_pop(0);
最後の 2 行は次のものと同等で、置き換えが可能である:
pthread_cleanup_pop(1);
上のコードは取り消し型が遅延 (deferred) である場合に限って
安全であることに注意すること (
pthread_setcanceltype
(3)を参照 ) 。
取り消し型が非同期 (asynchronous) の場合には、
スレッドの取り消しが
"pthread_cleanup_push"
と
"pthread_mutex_lock"
の間や、
"pthread_mutex_unlock"
と
"pthread_cleanup_pop"
の間で起こる可能性があり、
どちらの場合にもスレッドはカレントスレッドで
ロックしていない mutex をロック解除しようとしてしまう。
このことは非同期取り消しが使いにくいことの主な理由である。
上のコードが非同期取り消し型でも動作しなければならない場合、
mutex のロックおよびロック解除のために、
取り消し型を遅延 (deferred) に変更しなければならない:
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
pthread_cleanup_push(pthread_mutex_unlock, (void *) &mut);
pthread_mutex_lock(&mut);
/* do some work */
pthread_cleanup_pop(1);
pthread_setcanceltype(oldtype, NULL);
上のコードは、ポータブルでない関数
"pthread_cleanup_push_defer_np"
と
"pthread_cleanup_pop_restore_np"
を使うことで、よりコンパクトでより効率的な方法に書き直すことができる:
pthread_cleanup_push_restore_np(pthread_mutex_unlock, (void *) &mut);
pthread_mutex_lock(&mut);
/* do some work */
pthread_cleanup_pop_restore_np(1);
- Linux Tips 関連記事
- Linux Tips(目次)
- Linux ディストリビューション一覧
- rpm のファイル名にあるi386とかi686とは
- 自分のマシンの情報を調べる
- cron の設定
- ssh の root ログインを禁止する
- ssh を、ユーザ、IPでアクセス制限
- 鍵交換方式によるssh接続
- 鍵交換方式によるssh接続( windowsから )
- 複数ファイル内の文字列を置換して上書き保存する
- あるグループをイニシャルグループとするユーザー一覧出力
- 複数ファイルのファイル名を一括変換する
- 連番ファイルをコマンド一発で作成する
- 中身がランダムなファイルを任意のサイズで作成する
- Linux ユーザーアカウントをロック・アンロックする