OSDN Git Service

0984f564948ec7b99a1e662158cb16f9304be3d7
[linuxjm/LDP_man-pages.git] / release / man3 / pthread_cleanup_push.3
1 .\" Copyright (c) 2008 Linux Foundation, written by Michael Kerrisk
2 .\"     <mtk.manpages@gmail.com>
3 .\"
4 .\" %%%LICENSE_START(VERBATIM)
5 .\" Permission is granted to make and distribute verbatim copies of this
6 .\" manual provided the copyright notice and this permission notice are
7 .\" preserved on all copies.
8 .\"
9 .\" Permission is granted to copy and distribute modified versions of this
10 .\" manual under the conditions for verbatim copying, provided that the
11 .\" entire resulting derived work is distributed under the terms of a
12 .\" permission notice identical to this one.
13 .\"
14 .\" Since the Linux kernel and libraries are constantly changing, this
15 .\" manual page may be incorrect or out-of-date.  The author(s) assume no
16 .\" responsibility for errors or omissions, or for damages resulting from
17 .\" the use of the information contained herein.  The author(s) may not
18 .\" have taken the same level of care in the production of this manual,
19 .\" which is licensed free of charge, as they might when working
20 .\" professionally.
21 .\"
22 .\" Formatted or processed versions of this manual, if unaccompanied by
23 .\" the source, must acknowledge the copyright and authors of this work.
24 .\" %%%LICENSE_END
25 .\"
26 .\"*******************************************************************
27 .\"
28 .\" This file was generated with po4a. Translate the source file.
29 .\"
30 .\"*******************************************************************
31 .\"
32 .\" Japanese Version Copyright (c) 2012  Akihiro MOTOKI
33 .\"         all rights reserved.
34 .\" Translated 2012-06-04, Akihiro MOTOKI <amotoki@gmail.com>
35 .\"
36 .TH PTHREAD_CLEANUP_PUSH 3 2008\-11\-24 Linux "Linux Programmer's Manual"
37 .SH 名前
38 pthread_cleanup_push, pthread_cleanup_pop \- スレッドの
39 キャンセルクリーンアップハンドラの push/pop を行う
40 .SH 書式
41 .nf
42 \fB#include <pthread.h>\fP
43
44 \fBvoid pthread_cleanup_push(void (*\fP\fIroutine\fP\fB)(void *),\fP
45 \fB                          void *\fP\fIarg\fP\fB);\fP
46 \fBvoid pthread_cleanup_pop(int \fP\fIexecute\fP\fB);\fP
47 .sp
48 \fI\-pthread\fP でコンパイルしてリンクする。
49 .fi
50 .SH 説明
51 これらの関数は、呼び出したスレッドのスレッドキャンセル時のクリーンアッ
52 プハンドラのスタックの操作を行う。クリーンアップハンドラは、スレッドが
53 キャンセルされた場合 (や以下で説明する他の種々の状況において) 自動的に
54 実行される関数である。例えば、mutex のロック解除を行い、プロセス内の
55 他のスレッドが利用できるようにする関数などが考えられる。
56
57 \fBpthread_cleanup_push\fP() 関数は、 \fIroutine\fP をクリーンアップ
58 ハンドラのスタックの一番上にプッシュする。 \fIroutine\fP が後で
59 起動される際には、 \fIarg\fP が関数の引き数と渡される。
60
61 \fBpthread_cleanup_pop\fP() 関数は、クリーンアップハンドラの
62 スタックの一番上のルーチンを削除する。
63 \fIexecute\fP が 0 以外の場合にはそのルーチンを追加で実行する。
64
65 キャンセルクリーンアップハンドラは、以下に示す場合に
66 スタックから取り出され実行される。
67 .IP 1. 3
68 スレッドがキャンセルされた際に、スタックに登録された全てのクリーン
69 アップハンドラが取り出されて、実行される。クリーンアップハンドラの
70 実行は、スタックに登録されたのと逆の順序で行われる。
71 .IP 2.
72 スレッドが \fBpthread_exit\fP(3) を呼び出して終了する際に、全てのクリーン
73 アップハンドラが上の項目で述べたのと同様に実行される。
74 (スレッドがスレッド開始関数からの \fIreturn\fP の実行により終了する場合に
75 は、クリーンアップハンドラは\fI呼び出されない\fP。)
76 .IP 3.
77 スレッドが 0 以外の \fIexecute\fP 引き数で \fBpthread_cleanup_pop\fP() を
78 呼び出した際に、スタックの一番上のクリーンアップハンドラが取り出されて
79 実行される。
80 .PP
81 POSIX.1 では、 \fBpthread_cleanup_push\fP() と \fBpthread_cleanup_pop\fP() を
82 それぞれ \(aq\fB{\fP\(aq と \(aq\fB}\fP\(aq を含むテキストに展開するマクロと
83 して実装することを許容している。
84 このため、呼び出し側では、これらの関数の呼び出しが同じ関数の中で対と
85 なり、かつ文法的に同じネストレベル (nesting level) になることを保証
86 しなければならない。 (言い換えると、クリーンアップハンドラは、コード
87 の特定のセクションの実行の中でのみ設定するものであると言える。)
88
89 \fBlongjmp\fP(3) (\fBsiglongjmp\fP(3)) の呼び出しは、
90 \fBpthread_cleanup_push\fP() や \fBpthread_cleanup_pop\fP() の呼び出しが対と
91 なる呼び出しがない状態で行われた場合には、どのような結果になるかは不定
92 である。これは jump バッファは \fBsetjmp\fP(3) (\fBsigsetjmp\fP(3)) により設
93 定されるからである。同様に、クリーンアップハンドラ内からの
94 \fBlongjmp\fP(3) (\fBsiglongjmp\fP(3)) の呼び出しも、jump バッファがハンドラ
95 内で \fBsetjmp\fP(3) (\fBsigsetjmp\fP(3)) で設定されていない限り、どのような
96 結果になるかは不定である。
97 .SH 返り値
98 これらの関数は値を返さない。
99 .SH エラー
100 .\" SH VERSIONS
101 .\" Available since glibc 2.0
102 エラーはない。
103 .SH 準拠
104 POSIX.1\-2001.
105 .SH 注意
106 Linux では、関数 \fBpthread_cleanup_push\fP() と \fBpthread_cleanup_pop\fP()
107 は、それぞれ \(aq\fB{\fP\(aq と \(aq\fB}\fP\(aq を含むテキストに展開する
108 マクロとして実装されている。このことは、これらの関数を対で呼び出した
109 スコープ内で宣言された変数は、そのスコープの中でしか参照できない
110 ということを意味している。
111
112 .\" The text was actually added in the 2004 TC2
113 POSIX.1 には、括弧を含む \fBpthread_cleanup_push\fP() と
114 \fBpthread_cleanup_pop\fP() のブロックをそのままにしたままで、
115 \fIreturn\fP, \fIbreak\fP, \fIcontinue\fP, \fIgoto\fP を使った場合の影響は
116 不定であると書かれている。
117 移植性が必要なアプリケーションではこれを行うのは避けるべきである。
118 .SH 例
119 以下のプログラムは、このページで説明した関数の簡単な使用例を示すもので
120 ある。このプログラムは \fBpthread_cleanup_push\fP() と
121 \fBpthread_cleanup_pop\fP() で囲まれたループを実行するスレッドを作成する。
122 このループではグローバル変数 \fIcnt\fP を 1 秒に 1 ずつ増やしていく。
123 指定されたコマンドライン引き数の内容に基づいて、メインスレッドはもう一
124 つのスレッドにキャンセル要求を送ったり、もう一つのスレッドがループを
125 抜けて (\fIreturn\fP を呼び出して) 正常終了するようにグローバル変数を
126 設定したりする。
127
128 以下のシェルセッションでは、メインスレッドはもう一つのスレッドに
129 キャンセル要求を送信する。
130
131 .in +4n
132 .nf
133 $ \fB./a.out\fP
134 New thread started
135 cnt = 0
136 cnt = 1
137 Canceling thread
138 Called clean\-up handler
139 Thread was canceled; cnt = 0
140 .fi
141 .in
142
143 上記の実行例から、スレッドがキャンセルされ、
144 キャンセルクリーンアップハンドラが呼び出され、
145 グローバル変数 \fIcnt\fP の値が 0 にリセットされていることが確認できる。
146
147 次の実行例では、メインプログラムはグローバル変数を設定して、
148 もう一つのスレッドが正常終了するようにしている。
149
150 .in +4n
151 .nf
152 $ \fB./a.out x\fP
153 New thread started
154 cnt = 0
155 cnt = 1
156 Thread terminated normally; cnt = 2
157 .fi
158 .in
159
160 上記では、 (\fIcleanup_pop_arg\fP が 0 なので) クリーンアップハンドラは
161 実行されておらず、その結果 \fIcnt\fP の値はリセットされていないことが
162 分かる。
163
164 次の実行例では、メインプログラムはグローバル変数を設定して、
165 もう一つのスレッドが正常終了するようにし、さらに
166 \fIcleanup_pop_arg\fP に 0 以外の値を渡している。
167
168 .in +4n
169 .nf
170 $ \fB./a.out x 1\fP
171 New thread started
172 cnt = 0
173 cnt = 1
174 Called clean\-up handler
175 Thread terminated normally; cnt = 0
176 .fi
177 .in
178
179 上記では、スレッドはキャンセルされていないが、クリーンアップハンドラが
180 実行されていないことが分かる。これは \fBpthread_cleanup_pop\fP() の引き数
181 に 0 以外を渡したからである。
182 .SS プログラムのソース
183 \&
184 .nf
185 #include <pthread.h>
186 #include <sys/types.h>
187 #include <stdio.h>
188 #include <stdlib.h>
189 #include <unistd.h>
190 #include <errno.h>
191
192 #define handle_error_en(en, msg) \e
193         do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
194
195 static int done = 0;
196 static int cleanup_pop_arg = 0;
197 static int cnt = 0;
198
199 static void
200 cleanup_handler(void *arg)
201 {
202     printf("Called clean\-up handler\en");
203     cnt = 0;
204 }
205
206 static void *
207 thread_start(void *arg)
208 {
209     time_t start, curr;
210
211     printf("New thread started\en");
212
213     pthread_cleanup_push(cleanup_handler, NULL);
214
215     curr = start = time(NULL);
216
217     while (!done) {
218         pthread_testcancel();           /* A cancellation point */
219         if (curr < time(NULL)) {
220             curr = time(NULL);
221             printf("cnt = %d\en", cnt);  /* A cancellation point */
222             cnt++;
223         }
224     }
225
226     pthread_cleanup_pop(cleanup_pop_arg);
227     return NULL;
228 }
229
230 int
231 main(int argc, char *argv[])
232 {
233     pthread_t thr;
234     int s;
235     void *res;
236
237     s = pthread_create(&thr, NULL, thread_start, NULL);
238     if (s != 0)
239         handle_error_en(s, "pthread_create");
240
241     sleep(2);           /* Allow new thread to run a while */
242
243     if (argc > 1) {
244         if (argc > 2)
245             cleanup_pop_arg = atoi(argv[2]);
246         done = 1;
247
248     } else {
249         printf("Canceling thread\en");
250         s = pthread_cancel(thr);
251         if (s != 0)
252             handle_error_en(s, "pthread_cancel");
253     }
254
255     s = pthread_join(thr, &res);
256     if (s != 0)
257         handle_error_en(s, "pthread_join");
258
259     if (res == PTHREAD_CANCELED)
260         printf("Thread was canceled; cnt = %d\en", cnt);
261     else
262         printf("Thread terminated normally; cnt = %d\en", cnt);
263     exit(EXIT_SUCCESS);
264 }
265 .fi
266 .SH 関連項目
267 \fBpthread_cancel\fP(3), \fBpthread_cleanup_push_defer_np\fP(3),
268 \fBpthread_setcancelstate\fP(3), \fBpthread_testcancel\fP(3), \fBpthreads\fP(7)
269 .SH この文書について
270 この man ページは Linux \fIman\-pages\fP プロジェクトのリリース 3.65 の一部
271 である。プロジェクトの説明とバグ報告に関する情報は
272 http://www.kernel.org/doc/man\-pages/ に書かれている。