[インデックス 17340] ファイルの概要
このコミットは、Go言語の標準ライブラリ net
パッケージから、古くなった組み込みのネットワークポーリング機構を削除するものです。具体的には、BSD系のシステムで利用されていた kqueue
ベースのポーリング実装と、一般的なUnixシステムで利用されていた汎用ポーリング実装が削除されました。
コミット
commit ed738ad354dcd6722d1d7fffcc4a27fd10148e78
Author: Mikio Hara <mikioh.mikioh@gmail.com>
Date: Tue Aug 20 17:32:55 2013 +0900
net: remove obsolete builtin network pollster
Update #5199
Update #6146
R=golang-dev, dvyukov
CC=golang-dev
https://golang.org/cl/13112044
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/ed738ad354dcd6722d1d7fffcc4a27fd10148e78
元コミット内容
net: remove obsolete builtin network pollster
このコミットは、Goのネットワークパッケージから、もはや使用されていない組み込みのネットワークポーリング機構を削除します。関連するIssueとして #5199 と #6146 が挙げられています。
変更の背景
この変更の背景には、GoランタイムにおけるネットワークI/Oの非同期処理とスケジューリングの進化があります。初期のGoランタイムでは、ネットワークI/Oの待機(poll
、epoll
、kqueue
などのシステムコール)を処理するために、net
パッケージ内に独自のポーリング機構を持っていました。これは、Goのゴルーチン(goroutine)がブロッキングI/OによってOSスレッドをブロックしないようにするための重要なコンポーネントでした。
しかし、Go 1.1以降、ランタイムのスケジューラとネットワークポーラーの統合が進みました。特に、runtime
パッケージ内に、より汎用的で効率的なネットワークポーラー(netpoll
)が導入され、すべての非同期ネットワークI/Oがこの単一のポーラーによって処理されるようになりました。これにより、net
パッケージ内に個別に存在していたポーリング関連のコードは冗長となり、保守の負担となっていました。
このコミットは、その冗長なコードを削除し、ランタイムのnetpoll
に処理を一元化することで、コードベースの簡素化と効率化を図るものです。参照されているIssue #5199 と #6146 は、このポーリング機構の改善と統合に関連するものです。
前提知識の解説
このコミットを理解するためには、以下の前提知識が必要です。
-
非同期I/Oとポーリング:
- ブロッキングI/O: 通常のI/O操作は、データが利用可能になるまでプログラムの実行を停止(ブロック)させます。
- 非同期I/O: I/O操作の開始後、すぐに制御を呼び出し元に戻し、I/Oの完了は別のメカニズム(コールバック、イベントなど)で通知されます。これにより、I/O待機中に他の処理を進めることができます。
- ポーリング (Polling): 複数のI/Oディスクリプタ(ファイルディスクリプタ、ソケットなど)の状態を定期的にチェックし、読み書き可能になったものを検出するメカニズムです。Unix系OSでは
select
,poll
,epoll
(Linux),kqueue
(BSD/macOS) などのシステムコールがこれに該当します。これらは、多数のI/O操作を効率的に多重化するために使用されます。
-
Goランタイムとゴルーチン:
- ゴルーチン (Goroutine): Go言語の軽量な並行処理単位です。OSスレッドよりもはるかに軽量で、数百万個のゴルーチンを同時に実行できます。
- Goスケジューラ: ゴルーチンをOSスレッドにマッピングし、実行を管理するGoランタイムのコンポーネントです。ゴルーチンがブロッキングI/Oを行うと、スケジューラはそのゴルーチンをOSスレッドから切り離し、I/Oが完了するまで待機させます。I/Oが完了すると、ポーラーがスケジューラに通知し、スケジューラはゴルーチンを再び実行可能な状態に戻します。
- ネットワークポーラー (Netpoll): Goランタイムに組み込まれた特別なポーラーで、ネットワークI/Oの非同期処理を担当します。これにより、Goのネットワーク操作は、たとえブロッキングI/Oシステムコールを使用していたとしても、ゴルーチンレベルでは非同期に振る舞い、OSスレッドをブロックしません。
-
net
パッケージ:- Go言語の標準ライブラリで、TCP/IPネットワーク通信、UDP、Unixドメインソケットなどを扱うための機能を提供します。このパッケージの内部では、OSのネットワークI/Oシステムコールを効率的に利用するために、ランタイムのポーリング機構と連携しています。
技術的詳細
このコミットで削除されたファイルは以下の2つです。
-
src/pkg/net/fd_bsd.go
:- このファイルは、BSD系のOS(macOS, FreeBSDなど)で利用される
kqueue
/kevent
システムコールに基づいたポーリング機構を実装していました。 pollster
構造体がkqueue
ファイルディスクリプタとイベントバッファを保持し、AddFD
、DelFD
、WaitFD
などのメソッドを通じてファイルディスクリプタのイベントを監視していました。kqueue
は、イベント駆動型のI/O多重化メカニズムであり、ファイルディスクリプタの状態変化を効率的に通知します。
- このファイルは、BSD系のOS(macOS, FreeBSDなど)で利用される
-
src/pkg/net/fd_poll_unix.go
:- このファイルは、より一般的なUnix系OS(Linuxなど)で利用される
poll
システムコール(またはepoll
)に基づいたポーリング機構を実装していました。 pollServer
構造体がポーリングのメインループを管理し、pollDesc
構造体が個々のファイルディスクリプタの状態とデッドラインを管理していました。AddFD
、Evict
、Wakeup
、WaitRead
、WaitWrite
などのメソッドを通じて、ネットワークI/Oの待機と完了通知を行っていました。- この実装は、
os.Pipe
を使用してポーラー自身のウェイクアップ機構を実装するなど、複雑なロジックを含んでいました。
- このファイルは、より一般的なUnix系OS(Linuxなど)で利用される
これらのファイルが削除されたのは、Goランタイムのruntime
パッケージに、より統合されたnetpoll
機構が導入されたためです。runtime/netpoll.go
に実装されているnetpoll
は、OSごとのポーリングシステムコール(Linuxのepoll
、BSDのkqueue
、WindowsのI/O Completion Portsなど)を抽象化し、Goのスケジューラと密接に連携して動作します。これにより、net
パッケージはI/Oの待機を直接OSに依頼するのではなく、ランタイムのnetpoll
に委譲する形になりました。
この変更により、net
パッケージはポーリングの詳細な実装から解放され、より高レベルなネットワークプロトコルとAPIの提供に集中できるようになりました。また、ランタイムレベルでのポーリングの一元化は、パフォーマンスの向上、コードの簡素化、および保守性の向上に寄与します。
コアとなるコードの変更箇所
このコミットは、既存のコードの削除のみで構成されています。
src/pkg/net/fd_bsd.go
: ファイル全体が削除されました。src/pkg/net/fd_poll_unix.go
: ファイル全体が削除されました。
変更行数としては、fd_bsd.go
で123行、fd_poll_unix.go
で379行、合計502行の削除が行われています。
コアとなるコードの解説
削除されたコードは、Goのnet
パッケージが内部的に使用していた、OS固有の非同期I/Oポーリングメカニズムの実装でした。
fd_bsd.go
は、kqueue
システムコール(syscall.Kqueue
, syscall.Kevent
)を直接利用して、ファイルディスクリプタの読み書きイベントを監視していました。pollster
構造体はkqueue
インスタンスを管理し、AddFD
でイベントを登録し、WaitFD
でイベントを待機していました。
fd_poll_unix.go
は、より抽象化されたpollServer
とpollDesc
の概念を導入し、pollster
(このファイル内ではfd_bsd.go
や他のOS固有のポーラー実装をラップする形)を利用してI/Oイベントを処理していました。pollServer
はゴルーチンとしてバックグラウンドで動作し、登録されたファイルディスクリプタのイベントを監視し、イベントが発生した際にpollDesc
のチャネル(cr
, cw
)にエラーを送信することで、待機しているゴルーチンをウェイクアップしていました。また、デッドライン処理や、os.Pipe
を使ったポーラー自身のウェイクアップ機構も含まれていました。
これらのコードが削除されたことで、net
パッケージはこれらの低レベルなポーリング実装の詳細を知る必要がなくなり、Goランタイムのruntime/netpoll.go
に存在する統一されたネットワークポーラーに依存するようになりました。これにより、net
パッケージのコードはよりクリーンで、OS間の差異を意識する必要がなくなりました。
関連リンク
- Go Issue #5199: net: make net.pollServer use runtime.netpoll
- このIssueは、
net
パッケージのポーラーをruntime.netpoll
に移行することを提案しています。
- このIssueは、
- Go Issue #6146: net: remove obsolete pollster
- このIssueは、本コミットで削除された古いポーラーを削除することを提案しています。
- Go CL 13112044: net: remove obsolete builtin network pollster
- このコミットに対応するGoのコードレビューシステム(Gerrit)のチェンジリストです。
参考にした情報源リンク
- Goのソースコード(特に
src/runtime/netpoll.go
の現在の実装) - GoのIssueトラッカー(#5199, #6146)
- Goのドキュメントやブログ記事(Go 1.1以降のネットワークI/Oの変更に関するもの)
kqueue
、epoll
、poll
などのシステムコールに関するOSのドキュメント- Goの並行処理とスケジューラに関する一般的な解説記事