名 前
eventfd − イ ベ ン ト 通 知 用 の フ ァ イ ル デ ィ ス ク リ プ タ ー を 生 成 す る
書 式
#include <sys/eventfd.h>
int eventfd(unsigned int initval, int flags);
説 明
eventfd()
は "eventfd オ ブ ジ ェ
ク ト " を 生 成 す
る 。 eventfd オ ブ ジ
ェ ク ト は ユ ー
ザ ー 空 間 ア プ
リ ケ ー シ ョ ン
が イ ベ ン ト 待
ち 受 け /通 知 用
の 仕 組 み と し
て 使 う こ と が
で き る 。 ま た
、 カ ー ネ ル が
ユ ー ザ ー 空 間
ア プ リ ケ ー シ
ョ ン に イ ベ ン
ト を 通 知 す る
た め に も 使 う
こ と が で き る
。 こ の オ ブ ジ
ェ ク ト に は 、
unsigned の 64 ビ ッ ト 整
数 (uint64_t) 型 の カ
ウ ン タ ー が 含
ま れ て お り 、
こ の カ ウ ン タ
ー は カ ー ネ ル
に よ り 管 理 さ
れ る 。 こ の カ
ウ ン タ ー は initval
引 き 数 で 指 定
さ れ た 値 で 初
期 化 さ れ る 。
以 下 の 値 の い
く つ か を ビ ッ
ト 単 位 の 論 理
和 (OR) で 指 定 す る
こ と で 、 eventfd()
の 振 舞 い を 変
更 す る こ と が
で き る 。
EFD_CLOEXEC (Linux 2.6.27 以 降 ) 新
し い フ ァ イ ル
デ ィ ス ク リ プ
タ ー に 対 し て
close−on−exec (FD_CLOEXEC) フ
ラ グ を セ ッ ト
す る 。 こ の フ
ラ グ が 役 に 立
つ 理 由 に つ い
て は 、 open(2) の
O_CLOEXEC フ ラ グ の
説 明 を 参 照 の
こ と 。
EFD_NONBLOCK (Linux 2.6.27 以 降 ) 新
し く 生 成 さ れ
る オ ー プ ン フ
ァ イ ル 記 述 (open file
description) の O_NONBLOCK フ ァ
イ ル ス テ ー タ
ス フ ラ グ を セ
ッ ト す る 。 こ
の フ ラ グ を 使
う こ と で 、
O_NONBLOCK を セ ッ ト
す る た め に fcntl(2)
を 追 加 で 呼 び
出 す 必 要 が な
く な る 。
EFD_SEMAPHORE (Linux 2.6.30 以 降 ) 新
し い フ ァ イ ル
デ ィ ス ク リ プ
タ ー か ら の 読
み 出 し に お い
て 、 セ マ フ ォ
風 の 動 作 を 行
う 。 下 記 参 照
。 バ ー ジ ョ ン 2.6.26
以 前 の Linux で は 、
flags 引 き 数 は 未
使 用 で あ り 、 0
を 指 定 し な け
れ ば な ら な い
。
eventfd()
は eventfd オ ブ ジ ェ
ク ト を 参 照 す
る の に 使 用 で
き る 新 し い フ
ァ イ ル デ ィ ス
ク リ プ タ ー を
返 す 。 返 さ れ
た フ ァ イ ル デ
ィ ス ク リ プ タ
ー に 対 し て は
以 下 の 操 作 を
実 行 で き る 。
read(2) は
成 功 す る と 、 8
バ イ ト の 整 数
を 返 す 。 渡 さ
れ た バ ッ フ ァ
ー の 大 き さ が 8
バ イ ト 未 満 の
場 合 、 read(2) は エ
ラ ー EINVAL で 失 敗
す る 。 read(2)
が 返 す 値 は 、
ホ ス ト バ イ ト
オ ー ダ 、 つ ま
り 、 そ の ホ ス
ト マ シ ン に お
け る 整 数 の 通
常 の バ イ ト オ
ー ダ で あ る 。 read(2)
の 動 作 は 、 eventfd
カ ウ ン タ ー の
現 在 の 値 が 0 以
外 で あ る か と
、 eventfd フ ァ イ ル
デ ィ ス ク リ プ
タ ー を 作 成 す
る 際 に EFD_SEMAPHORE フ
ラ グ が 指 定 さ
れ た か 、 に よ
り 変 化 す る 。 * EFD_SEMAPHORE が 指 定 さ
れ て お ら ず 、
eventfd カ ウ ン タ ー
が 0 以 外 の 値 の
場 合 、 read(2) は カ
ウ ン タ ー 値 を
格 納 し た 8 バ イ
ト の 値 を 返 し
、 カ ウ ン タ ー
値 は 0 に リ セ ッ
ト さ れ る 。 * EFD_SEMAPHORE が 指 定 さ
れ て い て eventfd カ
ウ ン タ ー が 0 以
外 の 値 の 場 合
、 read(2) は 値 1 の 8
バ イ ト 値 を 返
し 、 カ ウ ン タ
ー 値 は 1 減 算 さ
れ る 。 * read(2) を 呼 び 出
し た 時 点 で eventfd
カ ウ ン タ ー が 0
の 場 合 、 read(2) は
カ ウ ン タ ー が 0
以 外 に な る ま
で 停 止 (block) す る (0
以 外 に な っ た
時 点 で read(2) は 上
記 で 述 べ た 通
り 実 行 を 再 開
す る )、 も し く
は フ ァ イ ル デ
ィ ス ク リ プ タ
ー が 非 停 止 (nonblocking)
に 設 定 さ れ て
い る 場 合 は エ
ラ ー EAGAIN で 失 敗
す る 。 write(2) は
、 引 き 数 の バ
ッ フ ァ ー で 渡
さ れ た 8 バ イ ト
の 整 数 値 を カ
ウ ン タ ー に 加
算 す る 。 カ ウ
ン タ ー に 格 納
可 能 な 最 大 値
は unsigned の 64 ビ ッ ト
整 数 の 最 大 値
か ら 1 を 引 い た
値 (す な わ ち
0xfffffffffffffffe) で あ る 。
加 算 を 行 う と
カ ウ ン タ ー 値
が 最 大 値 を 超
過 す る 場 合 に
は 、 そ の フ ァ
イ ル デ ィ ス ク
リ プ タ ー に 対
し て read(2) が 実 行
さ れ る ま で 、
write(2) は 停 止 (block) す
る 、 も し く は
フ ァ イ ル デ ィ
ス ク リ プ タ ー
が 非 停 止 (nonblocking) に
設 定 さ れ て い
る 場 合 は エ ラ
ー EAGAIN で 失 敗 す
る 。 渡 さ れ た
バ ッ フ ァ ー の
大 き さ が 8 バ イ
ト 未 満 の 場 合
、 も し く は 値
0xffffffffffffffff を 書 き 込
も う と し た 場
合 、 write(2) は エ ラ
ー EINVAL で 失 敗 す
る 。 poll(2),
select(2) (と 同 様 の
操 作 ) 返 さ れ た
フ ァ イ ル デ ィ
ス ク リ プ タ ー
は 、 poll(2) (epoll(7) も
同 じ ) や select(2) を
サ ポ ー ト し て
お り 、 以 下 の
よ う な 動 作 を
す る 。 * カ ウ ン タ ー
が 0 よ り 大 き い 値
の 場 合 、 フ ァ
イ ル デ ィ ス ク
リ プ タ ー は 読 み
出 し 可 能 と な
る (select(2) の readfds 引
き 数 や poll(2) の
POLLIN フ ラ グ )。 * 少 な く
と も 値 "1" を 、
停 止 (block) を 伴 わ
ず に 書 き 込 め
る 場 合 、 フ ァ イ
ル デ ィ ス ク リ
プ タ ー は 書 き
込 み 可 能 と な
る (select(2) の writefds 引
き 数 や poll(2) の
POLLOUT フ ラ グ )。 * カ ウ ン
タ ー 値 の オ ー
バ ー フ ロ ー が
検 出 さ れ た 場
合 、 フ ァ イ
ル デ ィ ス ク リ
プ タ ー は 読 み
出 し 可 能 と 書
き 込 み 可 能 の
両 方 を 通 知 し
、 poll(2) は POLLERR イ
ベ ン ト を 返 す
。 上 述 の 通 り
、 write(2) で カ ウ ン
タ ー が オ ー バ
ー フ ロ ー す る
こ と は 決 し て
な い 。 し か し
な が ら 、 KAIO サ ブ
シ ス テ ム に よ
っ て 2^64 回 の eventfd
"signal posts" が 実 行 さ
れ た 場 合 に は
オ ー バ ー フ ロ
ー が 起 こ り 得
る (理 論 的 に は
あ り 得 る が 、
実 用 的 に は あ
り 得 な い )。 オ
ー バ ー フ ロ ー
が 発 生 し た 場
合 、 read(2) は uint64_t
の 最 大 値 (す な
わ ち 0xffffffffffffffff) を 返
す 。 eventfd
フ ァ イ ル デ ィ
ス ク リ プ タ ー
は 、 こ れ 以 外
の フ ァ イ ル デ
ィ ス ク リ プ タ
ー 多 重 API で あ る
pselect(2) と ppoll(2) も サ
ポ ー ト し て い
る 。 close(2) フ
ァ イ ル デ ィ ス
ク リ プ タ ー が
そ れ 以 降 は 必
要 な く な っ た
際 に は 、 ク ロ
ー ズ す べ き で
あ る 。 同 じ eventfd
オ ブ ジ ェ ク ト
に 関 連 付 け ら
れ た フ ァ イ ル
デ ィ ス ク リ プ
タ ー が 全 て ク
ロ ー ズ さ れ る
と 、 そ の オ ブ
ジ ェ ク ト 用 の
資 源 が カ ー ネ
ル に よ り 解 放
さ れ る 。 fork(2)
で 生 成 さ れ た
子 プ ロ セ ス は
、 eventfd() で 生 成
さ れ た フ ァ イ
ル デ ィ ス ク リ
プ タ ー の コ ピ
ー を 継 承 す る
。 複 製 さ れ た
フ ァ イ ル デ ィ
ス ク リ プ タ ー
は 同 じ eventfd オ ブ
ジ ェ ク ト に 関
連 付 け ら れ る
。 close−on−exec フ ラ
グ が 設 定 さ れ
て い な い 場 合
、 execve(2) の 前 後
で eventfd() で 生 成
さ れ た フ ァ イ
ル デ ィ ス ク リ
プ タ ー は 保 持
さ れ る 。 成 功 す
る と 、 eventfd() は
新 規 の eventfd フ ァ
イ ル デ ィ ス ク
リ プ タ ー を 返
す 。 エ ラ ー の
場 合 、 −1 を 返
し 、 errno に エ ラ
ー を 示 す 値 を
設 定 す る 。 EINVAL flags に サ
ポ ー ト さ れ て
い な い 値 が 指
定 さ れ た 。 EMFILE オ ー プ
ン 済 み の フ ァ
イ ル デ ィ ス ク
リ プ タ ー の 数
が プ ロ セ ス あ
た り の 上 限 に
達 し て い た 。 ENFILE オ ー プ ン
済 み の フ ァ イ
ル 総 数 が シ ス
テ ム 全 体 の 上
限 に 達 し て い
た 。 ENODEV (カ
ー ネ ル 内 の ) 無
名 inode デ バ イ ス を
マ ウ ン ト で き
な か っ た 。 ENOMEM 新 し
い eventfd フ ァ
イ ル デ ィ ス ク
リ プ タ ー を 生
成 す る の に 十
分 な メ モ リ ー が
な か っ た 。 eventfd()
は カ ー ネ ル 2.6.22 以
降 の Linux で 利 用 可
能 で あ る 。 正
し く 動 作 す る glibc
側 の サ ポ ー ト
は バ ー ジ ョ ン 2.8
以 降 で 提 供 さ
れ て い る 。
eventfd2() シ ス テ ム
コ ー ル (「 注 意
」 参 照 ) は カ ー
ネ ル 2.6.27 以 降 の Linux
で 利 用 可 能 で
あ る 。 バ ー ジ
ョ ン 2.9 以 降 で は
、 glibc の eventfd() の ラ
ッ パ ー 関 数 は
、 カ ー ネ ル が
対 応 し て い れ
ば eventfd2() シ ス テ
ム コ ー ル を 利
用 す る 。 eventfd()
と eventfd2() は Linux 固 有
で あ る 。 ア プ リ
ケ ー シ ョ ン は
、 パ イ プ を イ
ベ ン ト を 通 知
す る た め だ け
に 使 用 し て い
る 全 て の 場 面
に お い て 、 パ
イ プ の 代 わ り
に eventfd フ ァ イ ル
デ ィ ス ク リ プ
タ ー を 使 用 す
る こ と が で き
る 。 eventfd フ ァ イ
ル デ ィ ス ク リ
プ タ ー を 使 う
方 が 、 パ イ プ
を 使 う 場 合 に
比 べ て カ ー ネ
ル で の オ ー バ
ヘ ッ ド は 比 べ
る と ず っ と 小
さ く 、 フ ァ イ
ル デ ィ ス ク リ
プ タ ー も 一 つ
し か 必 要 と し
な い (パ イ プ の
場 合 は 二 つ 必
要 で あ る )。 カ
ー ネ ル 内 で 使
用 す る と 、 eventfd
フ ァ イ ル デ ィ
ス ク リ プ タ ー
は カ ー ネ ル 空
間 か ら ユ ー ザ
ー 空 間 へ の ブ
リ ッ ジ 機 能 を
提 供 す る こ と
が で き 、 例 え
ば KAIO (kernel AIO) の よ う
な 機 能 が 、 あ
る フ ァ イ ル デ
ィ ス ク リ プ タ
ー に 何 ら か の
操 作 が 完 了 し
た こ と を 通 知
す る こ と が で
き る 。 eventfd
フ ァ イ ル デ ィ
ス ク リ プ タ ー
の 重 要 な 点 は
、 eventfd フ ァ イ ル
デ ィ ス ク リ プ
タ ー が select(2), poll(2),
epoll(7) を 使 っ て 他
の フ ァ イ ル デ
ィ ス ク リ プ タ
ー と 全 く 同 様
に 監 視 で き る
点 で あ る 。 こ
の こ と は 、 ア
プ リ ケ ー シ ョ
ン は 「 従 来 の
(traditional)」 フ ァ イ ル
の 状 態 変 化 と
eventfd イ ン タ ー フ
ェ ー ス を サ ポ
ー ト す る 他 の
カ ー ネ ル 機 構
の 状 態 変 化 を
同 時 に 監 視 で
き る こ と を 意
味 す る (eventfd() イ
ン タ ー フ ェ ー
ス が な い 時 に
は 、 こ れ ら の
カ ー ネ ル 機 構
は select(2), poll(2), epoll(7)
経 由 で 多 重 す
る こ と は で き
な か っ た )。 C ラ
イ ブ ラ リ と カ
ー ネ ル ABI の 違
い 下 層 に あ る
Linux シ ス テ ム コ ー
ル は 二 種 類 あ
り 、 eventfd() と 、
も っ と 新 し い
eventfd2() で あ る 。
eventfd() は flags 引 き
数 を 実 装 し て
い な い 。 eventfd2()
で は 上 記 の 値
の flags が 実 装 さ
れ て い る 。 glibc の
ラ ッ パ ー 関 数
は 、 eventfd2() が 利
用 可 能 で あ れ
ば 、 こ れ を 使
用 す る 。 glibc
の 追 加 機 能 typedef
uint64_t eventfd_t; int
eventfd_read(int fd, eventfd_t *value); 以 下 の
プ ロ グ ラ ム は
eventfd フ ァ イ ル デ
ィ ス ク リ プ タ
ー を 生 成 し 、
そ の 後 fork を 実 行
し て 子 プ ロ セ
ス を 生 成 す る
。 親 プ ロ セ ス
が 少 し の 間 sleep す
る 間 に 、 子 プ
ロ セ ス は プ ロ
グ ラ ム の コ マ
ン ド ラ イ ン 引
き 数 で 指 定 さ
れ た 整 数 (列 )を
そ れ ぞ れ eventfd フ
ァ イ ル デ ィ ス
ク リ プ タ ー に
書 き 込 む 。 親
プ ロ セ ス は sleep を
完 了 す る と eventfd
フ ァ イ ル デ ィ
ス ク リ プ タ ー
か ら 読 み 出 し
を 行 う 。 以 下
に 示 す シ ェ ル
セ ッ シ ョ ン に
こ の プ ロ グ ラ
ム の 使 い 方 を
示 す 。 $ ./a.out 1
2 4 7 14 #include <sys/eventfd.h>
#define
handle_error(msg) \ int if (argc <
2) { efd =
eventfd(0, 0); switch (fork())
{ exit(EXIT_SUCCESS); default: printf("Parent
about to read\n"); case −1:
futex(2),
pipe(2), poll(2), read(2),
select(2), signalfd(2),
timerfd_create(2), write(2), epoll(7),
sem_overview(7)
こ の man ペ
ー ジ は Linux man−pages
プ ロ ジ ェ ク ト
の リ リ ー ス 3.79 の
一 部 で あ る 。
プ ロ ジ ェ ク ト
の 説 明 と バ グ
報 告 に 関 す る
情 報 は
http://www.kernel.org/doc/man−pages/ に 書
か れ て い る 。
read(2)
返 り 値
エ ラ ー
バ ー ジ ョ ン
準 拠
注 意
GNU C ラ イ ブ ラ リ は
、 eventfd フ ァ イ ル
デ ィ ス ク リ プ
タ ー の 読 み 出
し と 書 き 込 み
に を 関 す る 詳
細 の い く つ か
抽 象 化 す る た
め に 、 一 つ の
型 と 、 二 つ の
関 数 を 追 加 で
定 義 し て い る
。
int eventfd_write(int fd, eventfd_t value); こ
れ ら の 関 数 は
、 eventfd フ ァ イ ル
デ ィ ス ク リ プ
タ ー に 対 す る
読 み 出 し と 書
き 込 み の 操 作
を 実 行 し 、 正
し い バ イ ト 数
が 転 送 さ れ た
場 合 に は 0 を 返
し 、 そ う で な
い 場 合 は −1 を
返 す 。例
Child writing 1 to efd
Child writing 2 to efd
Child writing 4 to efd
Child writing 7 to efd
Child writing 14 to efd
Child completed write loop
Parent about to read
Parent read 28 (0x1c) from efd プ ロ グ
ラ ム の ソ ー
ス
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h> /* Definition of uint64_t */
do { perror(msg); exit(EXIT_FAILURE); } while (0)
main(int argc, char *argv[])
{
int efd, j;
uint64_t u;
ssize_t s;
fprintf(stderr, "Usage: %s <num>...\n",
argv[0]);
exit(EXIT_FAILURE); }
if (efd == −1)
handle_error("eventfd");
case 0:
for (j = 1; j < argc; j++) {
printf("Child writing %s to efd\n", argv[j]);
u = strtoull(argv[j], NULL, 0);
/* strtoull() allows various bases */
s = write(efd, &u, sizeof(uint64_t));
if (s != sizeof(uint64_t))
handle_error("write"); }
printf("Child completed write loop\n");
sleep(2);
s = read(efd, &u, sizeof(uint64_t));
if (s != sizeof(uint64_t))
handle_error("read");
printf("Parent read %llu (0x%llx) from efd\n",
(unsigned long long) u, (unsigned long long) u);
exit(EXIT_SUCCESS);
handle_error("fork"); } }関 連 項 目
こ の 文 書 に つ い て