Man page - eventfd(2)

Packages contains this manual

Available languages:

en fr ja ru

Manual

EVENTFD

名 前
書 式
説 明
返 り 値
エ ラ ー
バ ー ジ ョ ン
属 性
準 拠
注 意
C ラ イ ブ ラ リ と カ ー ネ ル の 違 い
glibc の 追 加 機 能

プ ロ グ ラ ム の ソ ー ス
関 連 項 目
こ の 文 書 に つ い て

名 前

eventfd - イ ベ ン ト 通 知 用 の フ ァ イ ル デ ィ ス ク リ プ タ ー を 生 成 す る

書 式

#include <sys/eventfd.h>

int eventfd(unsigned int initval , int flags );

説 明

eventfd () は "eventfd オ ブ ジ ェ ク ト " を 生 成 す る 。 eventfd オ ブ ジ ェ ク ト は ユ ー ザ ー 空 間 ア プ リ ケ ー シ ョ ン が イ ベ ン ト 待 ち 受 け /通 知 用 の 仕 組 み と し て 使 う こ と が で き る 。 ま た 、 カ ー ネ ル が ユ ー ザ ー 空 間 ア プ リ ケ ー シ ョ ン に イ ベ ン ト を 通 知 す る た め に も 使 う こ と が で き る 。 こ の オ ブ ジ ェ ク ト に は 、 unsigned の 64 ビ ッ ト 整 数 ( uint64_t ) 型 の カ ウ ン タ ー が 含 ま れ て お り 、 こ の カ ウ ン タ ー は カ ー ネ ル に よ り 管 理 さ れ る 。 こ の カ ウ ン タ ー は initval 引 数 で 指 定 さ れ た 値 で 初 期 化 さ れ る 。

eventfd () は eventfd オ ブ ジ ェ ク ト を 参 照 す る の に 使 用 で き る 新 し い フ ァ イ ル デ ィ ス ク リ プ タ ー を 返 す 。

以 下 の 値 の い く つ か を ビ ッ ト 単 位 の 論 理 和 (OR) で 指 定 す る こ と で 、 eventfd () の 振 舞 い を 変 更 す る こ と が で き る 。
EFD_CLOEXEC
(Linux 2.6.27 以 降 )

新 し い フ ァ イ ル デ ィ ス ク リ プ タ ー に 対 し て close-on-exec ( FD_CLOEXEC ) フ ラ グ を セ ッ ト す る 。 こ の フ ラ グ が 役 に 立 つ 理 由 に つ い て は 、 open (2) の O_CLOEXEC フ ラ グ の 説 明 を 参 照 の こ と 。

EFD_NONBLOCK (Linux 2.6.27 以 降 )

Set the O_NONBLOCK file status flag on the open file description (see open (2)) referred to by the new file descriptor. Using this flag saves extra calls to fcntl (2) to achieve the same result.

EFD_SEMAPHORE (Linux 2.6.30 以 降 )

新 し い フ ァ イ ル デ ィ ス ク リ プ タ ー か ら の 読 み 出 し に お い て 、 セ マ フ ォ 風 の 動 作 を 行 う 。 下 記 参 照 。

バ ー ジ ョ ン 2.6.26 以 前 の Linux で は 、 flags 引 数 は 未 使 用 で あ り 、 0 を 指 定 し な け れ ば な ら な い 。

The following operations can be performed on the file descriptor returned by eventfd ():
read
(2)

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)

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 フ ラ グ )。

*

カ ウ ン タ ー 値 の オ ー バ ー フ ロ ー が 検 出 さ れ た 場 合 、 select (2) は フ ァ イ ル デ ィ ス ク リ プ タ ー は 読 み 出 し 可 能 と 書 き 込 み 可 能 の 両 方 を 通 知 し 、 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 () シ ス テ ム コ ー ル を 利 用 す る 。

属 性

こ の 節 で 使 用 さ れ て い る 用 語 の 説 明 に つ い て は 、 attributes (7) を 参 照 。

Image grohtml-7555-1.png

準 拠

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) 経 由 で 多 重 す る こ と は で き な か っ た )。

The current value of an eventfd counter can be viewed via the entry for the corresponding file descriptor in the process’s /proc/[pid]/fdinfo directory. See proc (5) for further details.

C ラ イ ブ ラ リ と カ ー ネ ル の 違 い

下 層 に あ る Linux シ ス テ ム コ ー ル は 二 種 類 あ り 、 eventfd () と 、 も っ と 新 し い eventfd2 () で あ る 。 eventfd () は flags 引 数 を 実 装 し て い な い 。 eventfd2 () で は 上 記 の 値 の flags が 実 装 さ れ て い る 。 glibc の ラ ッ パ ー 関 数 は 、 eventfd2 () が 利 用 可 能 で あ れ ば 、 こ れ を 使 用 す る 。

glibc の 追 加 機 能

GNU C ラ イ ブ ラ リ は 、 eventfd フ ァ イ ル デ ィ ス ク リ プ タ ー の 読 み 出 し と 書 き 込 み に を 関 す る 詳 細 の い く つ か 抽 象 化 す る た め に 、 一 つ の 型 と 、 二 つ の 関 数 を 追 加 で 定 義 し て い る 。

typedef uint64_t eventfd_t;

int eventfd_read(int fd, eventfd_t *value);
int eventfd_write(int fd, eventfd_t value);

こ れ ら の 関 数 は 、 eventfd フ ァ イ ル デ ィ ス ク リ プ タ ー に 対 す る 読 み 出 し と 書 き 込 み の 操 作 を 実 行 し 、 正 し い バ イ ト 数 が 転 送 さ れ た 場 合 に は 0 を 返 し 、 そ う で な い 場 合 は -1 を 返 す 。

以 下 の プ ロ グ ラ ム は eventfd フ ァ イ ル デ ィ ス ク リ プ タ ー を 生 成 し 、 そ の 後 fork を 実 行 し て 子 プ ロ セ ス を 生 成 す る 。 親 プ ロ セ ス が 少 し の 間 sleep す る 間 に 、 子 プ ロ セ ス は プ ロ グ ラ ム の コ マ ン ド ラ イ ン 引 数 で 指 定 さ れ た 整 数 (列 )を そ れ ぞ れ eventfd フ ァ イ ル デ ィ ス ク リ プ タ ー に 書 き 込 む 。 親 プ ロ セ ス は sleep を 完 了 す る と eventfd フ ァ イ ル デ ィ ス ク リ プ タ ー か ら 読 み 出 し を 行 う 。

以 下 に 示 す シ ェ ル セ ッ シ ョ ン に こ の プ ロ グ ラ ム の 使 い 方 を 示 す 。

$ ./a.out 1 2 4 7 14
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 <sys/eventfd.h>
#include <unistd.h>
#include <inttypes.h> /* Definition of PRIu64 & PRIx64 */
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h> /* Definition of uint64_t */

#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)

int
main(int argc, char *argv[])
{
int efd;
uint64_t u;
ssize_t s;

if (argc < 2) {
fprintf(stderr, "Usage: %s <num>...\n", argv[0]);
exit(EXIT_FAILURE);
}

efd = eventfd(0, 0);
if (efd == -1)
handle_error("eventfd");

switch (fork()) {
case 0:
for (int 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");

exit(EXIT_SUCCESS);

default:
sleep(2);

printf("Parent about to read\n");
s = read(efd, &u, sizeof(uint64_t));
if (s != sizeof(uint64_t))
handle_error("read");
printf("Parent read %"PRIu64" (%#"PRIx64") from efd\n", u, u);
exit(EXIT_SUCCESS);

case -1:
handle_error("fork");
}
}

関 連 項 目

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 プ ロ ジ ェ ク ト の リ リ ー ス 5.10 の 一 部 で あ る 。 プ ロ ジ ェ ク ト の 説 明 と バ グ 報 告 に 関 す る 情 報 は https://www.kernel.org/doc/man-pages/ に 書 か れ て い る 。