OSDN Git Service

Update README
[linuxjm/LDP_man-pages.git] / release / man7 / aio.7
1 .\" t
2 .\" Copyright (c) 2010 by Michael Kerrisk <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-05-02, Akihiro MOTOKI <amotoki@gmail.com>
35 .\"
36 .TH AIO 7 2014\-04\-06 Linux "Linux Programmer's Manual"
37 .SH 名前
38 aio \- POSIX 非同期 I/O の概要
39 .SH 説明
40 POSIX 非同期 (AIO) インターフェースを使うと、アプリケーションは、非同期
41 に (つまり、バックグラウンドで) 実行されるI/O 操作を一つ以上発行できる
42 ようになる。アプリケーションは I/O 操作の完了の通知方法を選択することが
43 できる。選択できる通知方法は、シグナルの配送、スレッドの起動、通知を行
44 わないである。
45
46 POSIX AIO インターフェースは以下の関数で構成されている。
47 .TP  16
48 \fBaio_read\fP(3)
49 読み出しリクエストをキューに入れる。
50 \fBread\fP(2) の非同期版である。
51 .TP 
52 \fBaio_write\fP(3)
53 書き込みリクエストをキューに入れる。
54 \fBwrite\fP(2) の非同期版である。
55 .TP 
56 \fBaio_fsync\fP(3)
57 ファイルディスクリプターに対して行われた I/O 操作の
58 同期 (sync) リクエストをキューに入れる。
59 \fBfsync\fP(2) や \fBfdatasync\fP(2) の非同期版である。
60 .TP 
61 \fBaio_error\fP(3)
62 キューに入れられた I/O リクエストのエラー状態を取得する。
63 .TP 
64 \fBaio_return\fP(3)
65 完了した I/O リクエストの終了ステータスを取得する。
66 .TP 
67 \fBaio_suspend\fP(3)
68 指定された I/O リクエストの集合 (要素は一つ以上) が完了するまで、
69 呼び出し側の実行を停止 (suspend) する。
70 .TP 
71 \fBaio_cancel\fP(3)
72 指定されたファイルディスクリプターに関する
73 完了していない I/O リクエストのキャンセルを試みる。
74 .TP 
75 \fBlio_listio\fP(3)
76 一回の関数呼び出しで複数の I/O リクエストをキューに入れる。
77 .PP
78 \fIaiocb\fP ("非同期 I/O 制御ブロック (asynchronous I/O control block)")
79 構造体は、I/O 操作を制御するパラメーターを定義する。この型の引き数は上記
80 の全ての関数で使用されている。この構造体は以下の通りである。
81 .PP
82 .in +4n
83 .nf
84 #include <aiocb.h>
85
86 struct aiocb {
87     /* The order of these fields is implementation\-dependent */
88
89     int             aio_fildes;     /* File descriptor */
90     off_t           aio_offset;     /* File offset */
91     volatile void  *aio_buf;        /* Location of buffer */
92     size_t          aio_nbytes;     /* Length of transfer */
93     int             aio_reqprio;    /* Request priority */
94     struct sigevent aio_sigevent;   /* Notification method */
95     int             aio_lio_opcode; /* Operation to be performed;
96                                        lio_listio() only */
97
98     /* Various implementation\-internal fields not shown */
99 };
100
101 /* Operation codes for \(aqaio_lio_opcode\(aq: */
102
103 enum { LIO_READ, LIO_WRITE, LIO_NOP };
104
105 .fi
106 .in
107 この構造体のフィールドは以下の通りである。
108 .TP  16
109 \fIaio_filedes\fP
110 I/O 操作の実行対象となるファイルディスクリプター。
111 .TP 
112 \fIaio_offset\fP
113 I/O 操作を行うファイルオフセットを示す。
114 .TP 
115 \fIaio_buf\fP
116 読み出し操作、書き込み操作でデータ転送に使用されるバッファー。
117 .TP 
118 \fIaio_nbytes\fP
119 \fIaio_buf\fP が指すバッファーのサイズ。
120 .TP 
121 \fIaio_reqprio\fP
122 このフィールドでは、呼び出したスレッドのリアルタイム優先度から
123 減算する値を指定する。この I/O リクエストの実行の優先度を
124 決定するために使用される (\fBpthread_setschedparam\fP(3) 参照)。
125 指定する値は 0 と \fIsysconf(_SC_AIO_PRIO_DELTA_MAX)\fP が返す値の間で
126 なければならない。このフィールドは、ファイル同期操作では無視される。
127 .TP 
128 \fIaio_sigevent\fP
129 このフィールドは、非同期 I/O 操作が完了した際に呼び出し側に
130 どのように通知を行うかを指定する構造体である。
131 \fIaio_sigevent.sigev_notify\fP に指定できる値は、
132 \fBSIGEV_NONE\fP, \fBSIGEV_SIGNAL\fP, \fBSIGEV_THREAD\fP である。
133 詳細は \fBsigevent\fP(7) を参照。
134 .TP 
135 \fIaio_lio_opcode\fP
136 実行される操作の種別。
137 \fBlio_listio\fP(3) でのみ使用される。
138 .PP
139 上記のリストにある標準の関数に加えて、GNU C ライブラリでは
140 以下に示す POSIX AIO API に対する拡張が提供されている。
141 .TP  16
142 \fBaio_init\fP(3)
143 glibc の POSIX AIO 実装の動作を調整するパラメーターを設定する。
144 .SH エラー
145 .TP 
146 \fBEINVAL\fP
147 \fIaiocb\fP 構造体の \fIaio_reqprio\fP フィールドが、0 より小さいか、
148 \fIsysconf(_SC_AIO_PRIO_DELTA_MAX)\fP が返す上限よりも大きかった。
149 .SH バージョン
150 POSIX AIO インターフェイスは glibc バージョン 2.1 以降で提供されている。
151 .SH 準拠
152 POSIX.1\-2001, POSIX.1\-2008.
153 .SH 注意
154 使用前に制御ブロックバッファーを 0 で埋めるのはよい考えである
155 (\fBmemset\fP(3) 参照)。I/O 操作が実行中の間は、制御ブロックバッファーと
156 \fIaio_buf\fP が指すバッファーを変更してはならない。I/O 操作が完了するまで、
157 これらのバッファーは有効な状態に保たなければならない。
158
159 同じ \fIaiocb\fP 構造体を使って、同時に複数の非同期の読み出し操作や
160 書き込み操作を行った場合に、どのような結果になるかは未定義である。
161
162 .\" http://lse.sourceforge.net/io/aio.html
163 .\" http://lse.sourceforge.net/io/aionotes.txt
164 .\" http://lwn.net/Articles/148755/
165 現在の Linux では、POSIX AIO 実装は glibc によりユーザー空間で提供
166 されている。このため、制限がいくつかあり、最も顕著なものは、I/O 操作を
167 実行する複数のスレッドの管理コストが高く、スケーラビリティに欠けること
168 である。しばらくの間、カーネルのステートマシンによる非同期 I/O の実装
169 の作業が行われているが (\fBio_submit\fP(2), \fBio_setup\fP(2),
170 \fBio_cancel\fP(2), \fBio_destroy\fP(2), \fBio_getevents\fP(2) 参照)、
171 この実装はまだ POSIX AIO 実装をカーネルシステムコールにより
172 再実装するほど成熟したものてはない。
173 .SH 例
174 下記のプログラムは、コマンドライン引き数で指定された名前のファイルを
175 それぞれオープンし、得られたファイルディスクリプターに対するリクエストを
176 \fBaio_read\fP(3) を使ってキューに入れる。その後、このプログラムはループに
177 入り、定期的に \fBaio_error\fP(3) を使ってまだ実行中の各 I/O 操作を監視す
178 る。各 I/O リクエストは、シグナルの配送による完了通知が行われるように設
179 定される。全ての I/O リクエストが完了した後、\fBaio_return\fP(3) を使って
180 それぞれのステータスを取得する。
181
182 \fBSIGQUIT\fP シグナル (control\-\e をタイプすると生成できる) を送ると、
183 このプログラムは \fBaio_cancel\fP(3) を使って
184 完了していない各リクエストにキャンセル要求を送る。
185
186 以下はこのプログラムを実行した際の出力例である。
187 この例では、標準入力に対して 2 つのリクエストを行い、
188 "abc" と "x" という 2 行の入力を行っている。
189
190 .in +4n
191 .nf
192 $ \fB./a.out /dev/stdin /dev/stdin\fP
193 opened /dev/stdin on descriptor 3
194 opened /dev/stdin on descriptor 4
195 aio_error():
196     for request 0 (descriptor 3): In progress
197     for request 1 (descriptor 4): In progress
198 \fBabc\fP
199 I/O completion signal received
200 aio_error():
201     for request 0 (descriptor 3): I/O succeeded
202     for request 1 (descriptor 4): In progress
203 aio_error():
204     for request 1 (descriptor 4): In progress
205 \fBx\fP
206 I/O completion signal received
207 aio_error():
208     for request 1 (descriptor 4): I/O succeeded
209 All I/O requests completed
210 aio_return():
211     for request 0 (descriptor 3): 4
212     for request 1 (descriptor 4): 2
213 .fi
214 .in
215 .SS プログラムのソース
216 \&
217 .nf
218 #include <stdlib.h>
219 #include <unistd.h>
220 #include <stdio.h>
221 #include <errno.h>
222 #include <aio.h>
223 #include <signal.h>
224
225 #define BUF_SIZE 20     /* Size of buffers for read operations */
226
227 #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)
228
229 #define errMsg(msg)  do { perror(msg); } while (0)
230
231 struct ioRequest {      /* Application\-defined structure for tracking
232                            I/O requests */
233     int           reqNum;
234     int           status;
235     struct aiocb *aiocbp;
236 };
237
238 static volatile sig_atomic_t gotSIGQUIT = 0;
239                         /* On delivery of SIGQUIT, we attempt to
240                            cancel all outstanding I/O requests */
241
242 static void             /* Handler for SIGQUIT */
243 quitHandler(int sig)
244 {
245     gotSIGQUIT = 1;
246 }
247
248 #define IO_SIGNAL SIGUSR1   /* Signal used to notify I/O completion */
249
250 static void                 /* Handler for I/O completion signal */
251 aioSigHandler(int sig, siginfo_t *si, void *ucontext)
252 {
253     write(STDOUT_FILENO, "I/O completion signal received\en", 31);
254
255     /* The corresponding ioRequest structure would be available as
256            struct ioRequest *ioReq = si\->si_value.sival_ptr;
257        and the file descriptor would then be available via
258            ioReq\->aiocbp\->aio_fildes */
259 }
260
261 int
262 main(int argc, char *argv[])
263 {
264     struct ioRequest *ioList;
265     struct aiocb *aiocbList;
266     struct sigaction sa;
267     int s, j;
268     int numReqs;        /* Total number of queued I/O requests */
269     int openReqs;       /* Number of I/O requests still in progress */
270
271     if (argc < 2) {
272         fprintf(stderr, "Usage: %s <pathname> <pathname>...\en",
273                 argv[0]);
274         exit(EXIT_FAILURE);
275     }
276
277     numReqs = argc \- 1;
278
279     /* Allocate our arrays */
280
281     ioList = calloc(numReqs, sizeof(struct ioRequest));
282     if (ioList == NULL)
283         errExit("calloc");
284
285     aiocbList = calloc(numReqs, sizeof(struct aiocb));
286     if (aiocbList == NULL)
287         errExit("calloc");
288
289     /* Establish handlers for SIGQUIT and the I/O completion signal */
290
291     sa.sa_flags = SA_RESTART;
292     sigemptyset(&sa.sa_mask);
293
294     sa.sa_handler = quitHandler;
295     if (sigaction(SIGQUIT, &sa, NULL) == \-1)
296         errExit("sigaction");
297
298     sa.sa_flags = SA_RESTART | SA_SIGINFO;
299     sa.sa_sigaction = aioSigHandler;
300     if (sigaction(IO_SIGNAL, &sa, NULL) == \-1)
301         errExit("sigaction");
302
303     /* Open each file specified on the command line, and queue
304        a read request on the resulting file descriptor */
305
306     for (j = 0; j < numReqs; j++) {
307         ioList[j].reqNum = j;
308         ioList[j].status = EINPROGRESS;
309         ioList[j].aiocbp = &aiocbList[j];
310
311         ioList[j].aiocbp\->aio_fildes = open(argv[j + 1], O_RDONLY);
312         if (ioList[j].aiocbp\->aio_fildes == \-1)
313             errExit("open");
314         printf("opened %s on descriptor %d\en", argv[j + 1],
315                 ioList[j].aiocbp\->aio_fildes);
316
317         ioList[j].aiocbp\->aio_buf = malloc(BUF_SIZE);
318         if (ioList[j].aiocbp\->aio_buf == NULL)
319             errExit("malloc");
320
321         ioList[j].aiocbp\->aio_nbytes = BUF_SIZE;
322         ioList[j].aiocbp\->aio_reqprio = 0;
323         ioList[j].aiocbp\->aio_offset = 0;
324         ioList[j].aiocbp\->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
325         ioList[j].aiocbp\->aio_sigevent.sigev_signo = IO_SIGNAL;
326         ioList[j].aiocbp\->aio_sigevent.sigev_value.sival_ptr =
327                                 &ioList[j];
328
329         s = aio_read(ioList[j].aiocbp);
330         if (s == \-1)
331             errExit("aio_read");
332     }
333
334     openReqs = numReqs;
335
336     /* Loop, monitoring status of I/O requests */
337
338     while (openReqs > 0) {
339         sleep(3);       /* Delay between each monitoring step */
340
341         if (gotSIGQUIT) {
342
343             /* On receipt of SIGQUIT, attempt to cancel each of the
344                outstanding I/O requests, and display status returned
345                from the cancellation requests */
346
347             printf("got SIGQUIT; canceling I/O requests: \en");
348
349             for (j = 0; j < numReqs; j++) {
350                 if (ioList[j].status == EINPROGRESS) {
351                     printf("    Request %d on descriptor %d:", j,
352                             ioList[j].aiocbp\->aio_fildes);
353                     s = aio_cancel(ioList[j].aiocbp\->aio_fildes,
354                             ioList[j].aiocbp);
355                     if (s == AIO_CANCELED)
356                         printf("I/O canceled\en");
357                     else if (s == AIO_NOTCANCELED)
358                             printf("I/O not canceled\en");
359                     else if (s == AIO_ALLDONE)
360                         printf("I/O all done\en");
361                     else
362                         errMsg("aio_cancel");
363                 }
364             }
365
366             gotSIGQUIT = 0;
367         }
368
369         /* Check the status of each I/O request that is still
370            in progress */
371
372         printf("aio_error():\en");
373         for (j = 0; j < numReqs; j++) {
374             if (ioList[j].status == EINPROGRESS) {
375                 printf("    for request %d (descriptor %d): ",
376                         j, ioList[j].aiocbp\->aio_fildes);
377                 ioList[j].status = aio_error(ioList[j].aiocbp);
378
379                 switch (ioList[j].status) {
380                 case 0:
381                     printf("I/O succeeded\en");
382                     break;
383                 case EINPROGRESS:
384                     printf("In progress\en");
385                     break;
386                 case ECANCELED:
387                     printf("Canceled\en");
388                     break;
389                 default:
390                     errMsg("aio_error");
391                     break;
392                 }
393
394                 if (ioList[j].status != EINPROGRESS)
395                     openReqs\-\-;
396             }
397         }
398     }
399
400     printf("All I/O requests completed\en");
401
402     /* Check status return of all I/O requests */
403
404     printf("aio_return():\en");
405     for (j = 0; j < numReqs; j++) {
406         ssize_t s;
407
408         s = aio_return(ioList[j].aiocbp);
409         printf("    for request %d (descriptor %d): %zd\en",
410                 j, ioList[j].aiocbp\->aio_fildes, s);
411     }
412
413     exit(EXIT_SUCCESS);
414 }
415 .fi
416 .SH 関連項目
417 .ad l
418 .nh
419 \fBio_cancel\fP(2), \fBio_destroy\fP(2), \fBio_getevents\fP(2), \fBio_setup\fP(2),
420 \fBio_submit\fP(2), \fBaio_cancel\fP(3), \fBaio_error\fP(3), \fBaio_init\fP(3),
421 \fBaio_read\fP(3), \fBaio_return\fP(3), \fBaio_write\fP(3), \fBlio_listio\fP(3)
422
423 .UR http://www.squid\-cache.org\:/~adrian\:/Reprint\-Pulavarty\-OLS2003.pdf
424 .UE
425 .SH この文書について
426 この man ページは Linux \fIman\-pages\fP プロジェクトのリリース 3.79 の一部
427 である。プロジェクトの説明とバグ報告に関する情報は
428 http://www.kernel.org/doc/man\-pages/ に書かれている。