1 .\" Copyright (C) 2008 Michael Kerrisk <mtk.manpages@gmail.com>
3 .\" %%%LICENSE_START(GPLv2+_SW_3_PARA)
4 .\" This program is free software; you can redistribute it and/or modify
5 .\" it under the terms of the GNU General Public License as published by
6 .\" the Free Software Foundation; either version 2 of the License, or
7 .\" (at your option) any later version.
9 .\" This program is distributed in the hope that it will be useful,
10 .\" but WITHOUT ANY WARRANTY; without even the implied warranty of
11 .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 .\" GNU General Public License for more details.
14 .\" You should have received a copy of the GNU General Public
15 .\" License along with this manual; if not, see
16 .\" <http://www.gnu.org/licenses/>.
19 .\" FIXME Linux 3.0: timerfd_settime() adds a TFD_TIMER_CANCEL_ON_SET flag;
20 .\" This flag needs to documented.
22 .\"*******************************************************************
24 .\" This file was generated with po4a. Translate the source file.
26 .\"*******************************************************************
28 .\" Japanese Version Copyright (c) 2008 Akihiro MOTOKI
29 .\" all rights reserved.
30 .\" Translated 2008-11-19, Akihiro MOTOKI <amotoki@dd.iij4u.or.jp>, LDP v3.13
31 .\" Updated 2009-04-24, Akihiro MOTOKI <amotoki@dd.iij4u.or.jp>, LDP 3.20
32 .\" Updated 2012-05-04, Akihiro MOTOKI <amotoki@gmail.com>
34 .TH TIMERFD_CREATE 2 2011\-09\-14 Linux "Linux Programmer's Manual"
36 timerfd_create, timerfd_settime, timerfd_gettime \- ファイルディスクリプタ経由で通知するタイマー
39 \fB#include <sys/timerfd.h>\fP
41 \fBint timerfd_create(int \fP\fIclockid\fP\fB, int \fP\fIflags\fP\fB);\fP
43 \fBint timerfd_settime(int \fP\fIfd\fP\fB, int \fP\fIflags\fP\fB,\fP
44 \fB const struct itimerspec *\fP\fInew_value\fP\fB,\fP
45 \fB struct itimerspec *\fP\fIold_value\fP\fB);\fP
47 \fBint timerfd_gettime(int \fP\fIfd\fP\fB, struct itimerspec *\fP\fIcurr_value\fP\fB);\fP
50 これらのシステムコールは、満了通知をファイルディスクリプタ経由で配送する タイマーの生成と操作を行う。 これらは、 \fBsetitimer\fP(2) や
51 \fBtimer_create\fP(2) を用いる方法の代わりとなるものであり、このファイルディスクリプタを \fBselect\fP(2),
52 \fBpoll\fP(2), \fBepoll\fP(7) で監視できるという利点がある。
55 これらのシステムコールを使うのは、それぞれ \fBtimer_create\fP(2), \fBtimer_settime\fP(2),
56 \fBtimer_gettime\fP(2) を使うのと同様である (\fBtimer_getoverrun\fP(2)
57 に対応するものはなく、以下で説明するように この機能は \fBread\fP(2) により提供される)。
60 .\" Additional clocks are now supported:
61 .\" CLOCK_REALTIME_ALARM and CLOCK_BOOTTIME_ALARM
62 .\" Since Linux 3.11, commit 11ffa9d6065f344a9bd769a2452f26f2f671e5f8
64 .\" Since Linux 3.15, commit 4a2378a943f09907fb1ae35c15de917f60289c14
65 \fBtimerfd_create\fP() は新規のタイマーオブジェクトを生成し、そのタイマーを参照するファイル ディスクリプタを返す。
66 \fIclockid\fP 引き数は、タイマーの進捗を管理するためのクロックを指定するもので、 \fBCLOCK_REALTIME\fP か
67 \fBCLOCK_MONOTONIC\fP のいずれかでなければならない。 \fBCLOCK_REALTIME\fP
68 はシステム全体で使用されるクロックで、このクロックは変更可能である。 \fBCLOCK_MONOTONIC\fP
69 は変更されることのないクロックで、(システム時刻の手動での変更などの) システムクロックの不連続な変化の影響を受けない。 これらのクロックの現在の値は
70 \fBclock_gettime\fP(2) を使って取得できる。
72 Linux 2.6.27 以降では、 以下の値のいくつかをビット単位の論理和 (OR) で指定することで、 \fBtimerfd_create\fP()
76 新しく生成されるオープンファイル記述 (open file description) の \fBO_NONBLOCK\fP
77 ファイルステータスフラグをセットする。 このフラグを使うことで、 \fBO_NONBLOCK\fP をセットするために \fBfcntl\fP(2)
81 新しいファイルディスクリプタに対して close\-on\-exec (\fBFD_CLOEXEC\fP) フラグをセットする。
82 このフラグが役に立つ理由については、 \fBopen\fP(2) の \fBO_CLOEXEC\fP フラグの説明を参照のこと。
84 バージョン 2.6.26 以前の Linux では、 \fIflags\fP 引き数は未使用であり、0 を指定しなければならない。
86 \fBtimerfd_settime\fP() は、ファイルディスクリプタ \fIfd\fP により参照されるタイマーを開始したり停止したりする。
88 \fInew_value\fP 引き数は、タイマーの満了時間 (expiration) の初期値と間隔 (interval) を
89 指定する。この引き数で使用されている \fIitimerspec\fP 構造体には 2 つのフィールドがあり、各フィールドは \fItimespec\fP
95 time_t tv_sec; /* Seconds */
96 long tv_nsec; /* Nanoseconds */
100 struct timespec it_interval; /* Interval for periodic timer */
101 struct timespec it_value; /* Initial expiration */
106 \fInew_value.it_value\fP はタイマーの満了時間の初期値を、秒とナノ秒で指定する。 \fInew_value.it_value\fP
107 のフィールドのうち少なくとも一方に 0 以外の値を設定すると、 タイマーが開始される。 両方のフィールドに 0 を設定すると、タイマーが停止する。
109 \fInew_value.it_interval\fP はタイマーの一回目の満了後に繰り返しタイマーの満了間隔を、秒とナノ秒で指定する。
110 \fInew_value.it_interval\fP のフィールドのうち少なくとも一方に 0 以外の値を設定すると、 繰り返しタイマーが有効になる。
111 両方のフィールドに 0 を設定した場合、タイマーは \fInew_value.it_value\fP で指定された時間後に、一回だけ満了して停止する。
113 \fIflags\fP 引き数には 0 か \fBTFD_TIMER_ABSTIME\fP を指定する。 0 は相対時刻タイマーを意味し、
114 \fInew_value.it_value\fP では \fIclockid\fP で指定されたクロックの現在の値からの相対的な時刻を指定する。
115 \fBTFD_TIMER_ABSTIME\fP は絶対時刻タイマーを意味し、 \fInew_value.it_interval\fP では \fIclockid\fP
116 で指定されたクロックの絶対時刻を指定する。 つまり、クロックの値が \fInew_value.it_interval\fP
117 で指定された時刻に達したら、タイマーが満了する。
120 \fIold_value\fP 引き数が NULL でない場合、 \fIold_value\fP 引き数が指す \fIitimerspec\fP 構造体は、
121 \fBtimerfd_settime\fP() を呼び出した時点でのタイマーの設定を返すのに使用される。 下記の \fBtimerfd_gettime\fP()
123 .SS timerfd_gettime()
124 \fBtimerfd_gettime\fP() は、ファイルディスクリプタ \fIfd\fP で参照されるタイマーの現在の設定が入った \fIitimerspec\fP
125 構造体を、 \fIcurr_value\fP に格納して返す。
127 \fIit_value\fP フィールドは、タイマーが次に満了するまでの残り時間を返す。 この構造体の両方のフィールドが 0
128 であれば、タイマーは現在停止している。 タイマー設定時に \fBTFD_TIMER_ABSTIME\fP
129 フラグが指定されたかに関わらず、このフィールドは常に相対値が格納される。
131 \fIit_interval\fP フィールドは、タイマーの間隔を返す。 この構造体の両方のフィールドが 0 であれば、タイマーは
132 \fInew_value.it_value\fP で指定された時間後に一回だけ満了して停止するように設定されている。
133 .SS タイマー・ファイルディスクリプタに対する操作
134 \fBtimerfd_create\fP() が返すファイルディスクリプタは以下の操作をサポートしている。
137 \fBtimerfd_settime\fP() を使ってタイマーの設定が最後変更されて以降、または \fBread\fP(2)
138 の呼び出しに最後に成功して以降に、タイマーの満了が一回以上発生していれば、 \fBread\fP(2) に渡されたバッファに、タイマー満了回数を示す 8
139 バイトの unsigned 型の整数 (\fIuint64_t\fP) が返される (返される値はホストバイトオーダ、つまりそのホストマシンにおける
142 \fBread\fP(2) を行った時点でタイマーの満了が発生していなければ、 \fBread\fP(2) は停止 (block)
143 する、もしくはファイルディスクリプタが 非停止 (nonblocking) に設定されている場合はエラー \fBEAGAIN\fP で失敗する
144 (非停止モードにするには、 \fBfcntl\fP(2) の \fBF_SETFL\fP 命令で \fBO_NONBLOCK\fP フラグをセットする)。
146 渡されたバッファの大きさが 8 バイト未満の場合、 \fBread\fP(2) はエラー \fBEINVAL\fP で失敗する。
148 \fBpoll\fP(2), \fBselect\fP(2) (と同様の操作)
149 一つ以上のタイマー満了が発生していれば、 ファイルディスクリプタは読み出し可能となる (\fBselect\fP(2) の \fIreadfds\fP 引き数や
150 \fBpoll\fP(2) の \fBPOLLIN\fP フラグ)。
152 このファイルディスクリプタは、他のファイルディスクリプタ多重 API である \fBpselect\fP(2), \fBppoll\fP(2),
153 \fBepoll\fP(7) もサポートしている。
157 ファイルディスクリプタがそれ以降は必要なくなった際には、クローズすべきである。 同じ timer
158 オブジェクトに関連付けられたファイルディスクリプタが全て クローズされると、そのタイマーは解除され、
159 そのオブジェクト用の資源がカーネルにより解放される。
162 \fBfork\fP(2) が行われると、子プロセスは \fBtimerfd_create\fP() により生成されたファイルディスクリプタのコピーを
163 継承する。そのファイルディスクリプタは、親プロセスの対応する ファイルディスクリプタと同じタイマーオブジェクトを参照しており、 子プロセスの
164 \fBread\fP(2) でも同じタイマーの満了に関する情報が返される。
166 \fBexecve\fP(2) の前後で \fBtimerfd_create\fP() により生成されたファイルディスクリプタは保持され、
167 タイマーが開始されていた場合にはタイマーの満了が発生し続ける。
169 成功すると、 \fBtimerfd_create\fP() は新しいファイルディスクリプタを返す。 エラーの場合、\-1 を返し、 \fIerrno\fP
172 \fBtimerfd_settime\fP() と \fBtimerfd_gettime\fP() は成功すると 0 を返す。 エラーの場合、\-1 を返し、
173 \fIerrno\fP にエラーを示す値を設定する。
175 \fBtimerfd_create\fP() は以下のエラーで失敗する可能性がある。
178 \fIclockid\fP 引き数が \fBCLOCK_MONOTONIC\fP でも \fBCLOCK_REALTIME\fP でもない。
181 \fIflags\fP が無効である。もしくは、Linux 2.6.26 以前の場合には \fIflags\fP が 0 以外である。
184 オープン済みのファイルディスクリプタの数がプロセスあたりの上限に 達していた。
187 オープン済みのファイル総数がシステム全体の上限に達していた。
190 (カーネル内の) 無名 inode デバイスをマウントできなかった。
193 タイマーを作成するのに十分なカーネルメモリがなかった。
195 \fBtimerfd_settime\fP() と \fBtimerfd_gettime\fP() は以下のエラーで失敗する可能性がある。
198 \fIfd\fP が有効なファイルディスクリプタでない。
201 \fInew_value\fP, \fIold_value\fP, \fIcurr_value\fP が有効なポインタではない。
204 \fIfd\fP が有効な timerfd ファイルディスクリプタでない。
206 \fBtimerfd_settime\fP() は以下のエラーで失敗することもある。
209 \fInew_value\fP が適切に初期化されていない (\fItv_nsec\fP の一つが 0 から 999,999,999 までの範囲に入っていない)。
212 .\" This case only checked since 2.6.29, and 2.2.2[78].some-stable-version.
213 .\" In older kernel versions, no check was made for invalid flags.
216 これらのシステムコールはカーネル 2.6.25 以降の Linux で利用可能である。 ライブラリ側のサポートはバージョン 2.8 以降の glibc
219 これらのシステムコールは Linux 固有である。
222 現在のところ、 \fBtimerfd_create\fP() が対応している clockid の種類は \fBtimer_create\fP(2)
225 以下のプログラムは、タイマーを作成し、その進捗をモニターするものである。 このプログラムは最大で 3 個のコマンドライン引き数を取り、
226 第一引き数ではタイマーの満了時間の初期値 (秒数単位) を、 第二引き数ではタイマーの間隔 (秒数単位) を、
227 第三引き数ではタイマーが何回満了したらプログラムが終了するかを指定する。 第二引き数と第三引き数は省略可能である。
229 以下のシェルのセッションはこのプログラムの使用例を示したものである。
233 $\fB a.out 3 1 100\fP
235 3.000: read: 1; total=1
236 4.000: read: 1; total=2
237 \fB^Z \fP # type control\-Z to suspend the program
238 [1]+ Stopped ./timerfd3_demo 3 1 100
239 $ \fBfg\fP # Resume execution after a few seconds
241 9.660: read: 5; total=7
242 10.000: read: 1; total=8
243 11.000: read: 1; total=9
244 \fB^C \fP # type control\-C to suspend the program
250 .\" The commented out code here is what we currently need until
251 .\" the required stuff is in glibc
254 .\"/* Link with -lrt */
255 .\"#define _GNU_SOURCE
256 .\"#include <sys/syscall.h>
257 .\"#include <unistd.h>
259 .\"#if defined(__i386__)
260 .\"#define __NR_timerfd_create 322
261 .\"#define __NR_timerfd_settime 325
262 .\"#define __NR_timerfd_gettime 326
266 .\"timerfd_create(int clockid, int flags)
268 .\" return syscall(__NR_timerfd_create, clockid, flags);
272 .\"timerfd_settime(int fd, int flags, struct itimerspec *new_value,
273 .\" struct itimerspec *curr_value)
275 .\" return syscall(__NR_timerfd_settime, fd, flags, new_value,
280 .\"timerfd_gettime(int fd, struct itimerspec *curr_value)
282 .\" return syscall(__NR_timerfd_gettime, fd, curr_value);
285 .\"#define TFD_TIMER_ABSTIME (1 << 0)
287 .\"////////////////////////////////////////////////////////////
288 #include <sys/timerfd.h>
293 #include <stdint.h> /* Definition of uint64_t */
295 #define handle_error(msg) \e
296 do { perror(msg); exit(EXIT_FAILURE); } while (0)
299 print_elapsed_time(void)
301 static struct timespec start;
302 struct timespec curr;
303 static int first_call = 1;
308 if (clock_gettime(CLOCK_MONOTONIC, &start) == \-1)
309 handle_error("clock_gettime");
312 if (clock_gettime(CLOCK_MONOTONIC, &curr) == \-1)
313 handle_error("clock_gettime");
315 secs = curr.tv_sec \- start.tv_sec;
316 nsecs = curr.tv_nsec \- start.tv_nsec;
321 printf("%d.%03d: ", secs, (nsecs + 500000) / 1000000);
325 main(int argc, char *argv[])
327 struct itimerspec new_value;
330 uint64_t exp, tot_exp;
333 if ((argc != 2) && (argc != 4)) {
334 fprintf(stderr, "%s init\-secs [interval\-secs max\-exp]\en",
339 if (clock_gettime(CLOCK_REALTIME, &now) == \-1)
340 handle_error("clock_gettime");
342 /* Create a CLOCK_REALTIME absolute timer with initial
343 expiration and interval as specified in command line */
345 new_value.it_value.tv_sec = now.tv_sec + atoi(argv[1]);
346 new_value.it_value.tv_nsec = now.tv_nsec;
348 new_value.it_interval.tv_sec = 0;
351 new_value.it_interval.tv_sec = atoi(argv[2]);
352 max_exp = atoi(argv[3]);
354 new_value.it_interval.tv_nsec = 0;
356 fd = timerfd_create(CLOCK_REALTIME, 0);
358 handle_error("timerfd_create");
360 if (timerfd_settime(fd, TFD_TIMER_ABSTIME, &new_value, NULL) == \-1)
361 handle_error("timerfd_settime");
363 print_elapsed_time();
364 printf("timer started\en");
366 for (tot_exp = 0; tot_exp < max_exp;) {
367 s = read(fd, &exp, sizeof(uint64_t));
368 if (s != sizeof(uint64_t))
369 handle_error("read");
372 print_elapsed_time();
373 printf("read: %llu; total=%llu\en",
374 (unsigned long long) exp,
375 (unsigned long long) tot_exp);
382 \fBeventfd\fP(2), \fBpoll\fP(2), \fBread\fP(2), \fBselect\fP(2), \fBsetitimer\fP(2),
383 \fBsignalfd\fP(2), \fBtimer_create\fP(2), \fBtimer_gettime\fP(2),
384 \fBtimer_settime\fP(2), \fBepoll\fP(7), \fBtime\fP(7)
386 この man ページは Linux \fIman\-pages\fP プロジェクトのリリース 3.76 の一部である。
387 プロジェクトの説明とバグ報告に関する情報は \%http://www.kernel.org/doc/man\-pages/ に書かれている。