0Pricing
C Academy · レッスン

epollをセットアップする

epollセットを作成して登録します。

「epollをセットアップする」はCoddyKit上の無料C Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C Academyコースには全4レッスンが含まれています。

epollインスタンスの作成

すべては、ファイルディスクリプタでもあるepollインスタンスから始まります。epoll_create1()で作成します。

引数はフラグフィールドです。デフォルトの動作にする場合は0を、exec()をまたいでディスクリプタを自動的に閉じる場合はEPOLL_CLOEXECを渡します。返されたfdを、以降のすべてのepoll呼び出しに渡します。

int epfd = epoll_create1(EPOLL_CLOEXEC);
if (epfd == -1) { perror("epoll_create1"); exit(1); }

epoll_create1とepoll_createの違い

古いepoll_create(int size)はサイズのヒントを受け取っていましたが、現在のカーネルはこれを無視します。必要なのは、値が正数であることだけでした。

epoll_create1()を使用してください。意味のないサイズではなくフラグを受け取り、EPOLL_CLOEXECをアトミックに指定できるため、別途fcntl()を呼び出す必要がありません。

/* legacy form, size arg ignored by kernel */
int epfd = epoll_create(1);

epoll_event構造体

監視対象と結果は、どちらもstruct epoll_eventで表します。eventsビットマスクとdata共用体を持ちます。

data共用体には、イベント発生時に返してほしい値を格納します。一般的にはdata.fdを使いますが、確保した接続オブジェクトを指すdata.ptrを格納することもできます。

struct epoll_event ev;
ev.events = EPOLLIN;
ev.data.fd = listen_fd;

EPOLL_CTL_ADDによる登録

epoll_ctl()で監視対象リストを管理します。ディスクリプタの監視を開始するには、EPOLL_CTL_ADD操作を使用します。

epoll fd、操作、対象fd、およびepoll_eventへのポインタを渡します。これ以降、epollはそのディスクリプタの準備完了を通知します。

struct epoll_event ev = { .events = EPOLLIN, .data.fd = listen_fd };
if (epoll_ctl(epfd, EPOLL_CTL_ADD, listen_fd, &ev) == -1)
    perror("epoll_ctl: add");

イベントフラグ: EPOLLINとEPOLLOUT

eventsマスクで、何を監視するかを指定します。EPOLLINはディスクリプタが読み取り可能であることを、EPOLLOUTは書き込み可能であることを意味します。

通常、接続待ちソケットでは接続を受け付けるためにEPOLLINを監視し、クライアントソケットでも読み取りのためにEPOLLINを監視します。EPOLLOUTを追加するのは、送信しきれなかったデータをバッファリングしている場合だけにしてください。

ev.events = EPOLLIN | EPOLLOUT;

エラーと切断のフラグ

カーネルは、要求していない場合でも特定の状態を常に通知します。EPOLLERRはエラー、EPOLLHUPは切断、EPOLLRDHUPは相手側によるハーフクローズを表します。

ハンドラーでこれらを確認してください。切断されたソケットのEPOLLHUPを無視すると、イベントループが空回りします。

if (ev.events & (EPOLLERR | EPOLLHUP)) {
    close(ev.data.fd);
    continue;
}

EPOLL_CTL_MODによる監視対象の変更

ディスクリプタを登録した後でも、登録を解除せずにイベントマスクを変更できます。EPOLL_CTL_MODを使用します。

よくあるパターンは、通常はEPOLLINだけを監視し、送信バッファがいっぱいになったらEPOLLIN | EPOLLOUTに切り替え、送信し終わったら元に戻す方法です。

ev.events = EPOLLIN | EPOLLOUT;
ev.data.fd = conn_fd;
epoll_ctl(epfd, EPOLL_CTL_MOD, conn_fd, &ev);

EPOLL_CTL_DELによる削除

接続を閉じるときは、EPOLL_CTL_DELで監視を停止します。最後のepoll_event引数は無視されるため、最近のカーネルではNULLを指定できます。

ディスクリプタを閉じると、すべてのepoll監視対象リストから自動的に削除されます。ただし、閉じる前に明示的に削除しておくと、管理状態が分かりやすくなります。

epoll_ctl(epfd, EPOLL_CTL_DEL, conn_fd, NULL);
close(conn_fd);

レベルトリガーとエッジトリガー

デフォルトでは、epollはレベルトリガーです。ディスクリプタが読み取り可能なままである限り、すべてのepoll_wait()で通知されます。扱いやすく、実装も簡単です。

EPOLLETフラグを追加すると、エッジトリガーモードになります。準備状態が変化したときだけ通知されるため、EAGAINになるまでループしてソケットを完全に読み出す必要があります。

ev.events = EPOLLIN | EPOLLET;  /* edge-triggered */
epoll_ctl(epfd, EPOLL_CTL_ADD, conn_fd, &ev);

コンテキストポインタの格納

data.fdの代わりに、接続ごとの構造体を指すdata.ptrを格納できます。イベントが発生すると、そのポインタを直接取得できるため、検索テーブルは必要ありません。

ただし、これは共用体であることを忘れないでください。data.ptrを設定した場合、同じイベントからdata.fdも読み取ることはできません。

struct conn *c = malloc(sizeof *c);
c->fd = conn_fd;
ev.events = EPOLLIN;
ev.data.ptr = c;
epoll_ctl(epfd, EPOLL_CTL_ADD, conn_fd, &ev);

後処理

epollインスタンスは単なるファイルディスクリプタなので、サーバーの終了時にclose()で解放します。

epoll fdを閉じると、カーネルの監視対象リストが解放されます。まだ開いている監視対象ソケットは開いたままなので、リソースを解放するには別途閉じてください。

close(epfd);

確認テスト

epollのセットアップAPIを理解できているか確認しましょう。

まとめ

epoll_create1()でインスタンスを作成し、epoll_ctl()でADD、MOD、DELを使って監視対象を管理します。各struct epoll_eventには、eventsマスクとdata共用体が格納されます。

簡潔さを重視する場合はレベルトリガーを、エッジトリガーの性能を活用する場合はEPOLLETを選択します。次は、これらの要素をイベントループから動かします。

よくある質問

「epollをセットアップする」レッスンは無料ですか?

はい。「epollをセットアップする」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C Academyコースには全4レッスンが含まれています。

「epollをセットアップする」で何を学びますか?

epollセットを作成して登録します。 ブラウザで直接実行するハンズオンコードでC Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「epollをセットアップする」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC Academyレッスンでコードを書いて実行できますか?

はい。すべてのC Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. ブロッキングI/OとノンブロッキングI/O
  2. epollをセットアップする
  3. イベントループ
  4. シンプルなエコーサーバー
← C Academyに戻る