Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 19378] ファイルの概要

このコミットは、Go 1.3のリリースノートを記述したdoc/go1.3.htmlファイルに、syscallパッケージの新しい関数SendmsgNに関する記述を追加するものです。SendmsgNは、既存のSendmsg関数の代替として、書き込まれたバイト数を返す機能を提供します。これは、Goの低レベルネットワーク操作における情報提供の改善を目的としています。

コミット

  • コミットハッシュ: 1704368c5d4de51dad3c46d833e93dfe78fddaa2
  • Author: Mikio Hara mikioh.mikioh@gmail.com
  • Date: Fri May 16 13:18:14 2014 +0900

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/1704368c5d4de51dad3c46d833e93dfe78fddaa2

元コミット内容

doc/go1.3.html: add syscall.SendmsgN

LGTM=iant
R=golang-codereviews, iant
CC=golang-codereviews
https://golang.org/cl/93430044

変更の背景

Go言語のsyscallパッケージは、オペレーティングシステム(OS)の低レベルなシステムコールにアクセスするための機能を提供します。ネットワーク通信において、sendmsgシステムコールは、通常のデータペイロードに加えて、補助データ(ancillary data)と呼ばれる追加情報を送信する際に利用されます。Goのsyscallパッケージには、このsendmsgシステムコールをラップしたSendmsg関数が以前から存在していました。

しかし、従来のsyscall.Sendmsg関数は、操作が成功したかどうかを示すエラー情報のみを返していました。これは、送信されたバイト数を正確に把握したい場合や、部分的な書き込みが発生した場合に不十分でした。特に、ネットワークプログラミングにおいては、実際にどれだけのデータが送信されたかを知ることが、信頼性の高い通信プロトコルを実装したり、デバッグを行ったりする上で非常に重要です。

このコミットは、Go 1.3のリリースにおいて、この情報不足を解消するためにsyscall.SendmsgNが導入されたことをドキュメントに追記するものです。SendmsgNは、Sendmsgと同様の機能を提供しつつ、実際に書き込まれたバイト数を戻り値として返すことで、より詳細な情報を提供できるようになりました。これにより、開発者は低レベルなネットワーク操作において、より堅牢で情報量の多いコードを記述できるようになります。

前提知識の解説

Go言語のsyscallパッケージ

syscallパッケージは、Goプログラムから直接OSのシステムコールを呼び出すための低レベルなインターフェースを提供します。これにより、ファイル操作、プロセス管理、ネットワーク通信など、OSが提供する基本的な機能にアクセスできます。ただし、syscallパッケージはOSに依存する部分が大きく、異なるOS間での移植性(ポータビリティ)が低いという特性があります。そのため、通常はosnetといった高レベルな標準ライブラリを使用することが推奨されますが、特定の高度な機能やパフォーマンスが求められる場合にはsyscallパッケージが利用されます。

sendmsgシステムコール

sendmsgは、Unix系OSで利用されるシステムコールの一つで、ソケットを介してメッセージを送信するために使用されます。このシステムコールの特徴は、通常のデータ(ペイロード)だけでなく、「補助データ(ancillary data)」と呼ばれる追加情報を同時に送信できる点にあります。補助データは、ファイルディスクリプタの転送(SCM_RIGHTS)や、ソケットオプションの設定など、様々な用途に利用されます。

補助データ (Ancillary Data)

補助データは、sendmsgシステムコールで通常のデータとは別に送信される制御情報です。例えば、Unixドメインソケットを介してプロセス間でファイルディスクリプタを転送する際に使用されるSCM_RIGHTSが代表的です。これにより、異なるプロセス間でオープンなファイルやソケットの所有権を安全に受け渡すことが可能になります。

syscall.Sendmsgsyscall.SendmsgNの違い

  • syscall.Sendmsg: 従来の関数で、sendmsgシステムコールをラップします。引数としてファイルディスクリプタ、データペイロード、補助データ、宛先アドレス、フラグを受け取ります。戻り値はエラーのみで、送信が成功したか失敗したかを示します。
  • syscall.SendmsgN: Sendmsgと同様の引数を受け取りますが、戻り値として「書き込まれたバイト数(n int)」と「エラー(err error)」を返します。これにより、実際にどれだけのデータが送信されたかを正確に知ることができます。

技術的詳細

sendmsgシステムコールは、その性質上、部分的な書き込みが発生する可能性があります。例えば、送信バッファの空き容量が不足している場合や、ネットワークの輻輳などにより、指定したデータの一部しか一度に送信できないことがあります。従来のsyscall.Sendmsgでは、このような部分的な書き込みが発生した場合でも、エラーが発生しない限り成功と見なされてしまい、開発者は実際に送信されたバイト数を把握できませんでした。

syscall.SendmsgNの導入は、この問題に対処するためのものです。SendmsgNは、OSのsendmsgシステムコールが返す実際のバイト数をGoの関数呼び出しの戻り値として透過的に公開します。これにより、開発者は送信操作の完了後に、実際に送信されたバイト数を確認し、必要に応じて残りのデータを再送するなどのロジックを実装できるようになります。

この機能は、特に以下のようなシナリオで重要となります。

  • 信頼性の高いプロトコル実装: アプリケーション層で独自の信頼性プロトコルを実装する際、送信確認や再送処理のために正確な送信バイト数が必要となります。
  • パフォーマンス測定とデバッグ: ネットワーク通信のパフォーマンスを測定したり、問題のデバッグを行ったりする際に、実際に送信されたデータ量を把握することは不可欠です。
  • ゼロコピー転送: 一部のOSでは、sendmsgがゼロコピー転送(ユーザー空間とカーネル空間の間でデータをコピーせずに転送する技術)をサポートしている場合があります。このような高度な最適化を利用する際にも、正確な送信バイト数の把握が重要になります。

Goの標準ライブラリは、通常、OS依存の低レベルな詳細を抽象化し、よりポータブルで使いやすいインターフェースを提供することを目指しています。しかし、syscallパッケージは、その性質上、OSの特性を直接反映する部分が多くなります。SendmsgNの追加は、この低レベルなインターフェースにおいても、開発者が必要とする詳細な情報を提供することで、より高度なネットワークアプリケーションの構築を支援するというGoの設計思想の一端を示しています。

コアとなるコードの変更箇所

このコミットは、Go 1.3のリリースノートを記述したdoc/go1.3.htmlファイルのみを変更しています。実際のsyscall.SendmsgN関数の実装は、このコミット以前に行われています。

diff --git a/doc/go1.3.html b/doc/go1.3.html
index 056c4cbe81..bf72a052e7 100644
--- a/doc/go1.3.html
+++ b/doc/go1.3.html
@@ -457,6 +457,14 @@ now considers the <code>DEL</code> character, <code>U+007F</code>, to be
 non-printing.
 </li>
 
+<li>
+The <a href="/pkg/syscall/"><code>syscall</code></a> package now provides
+<a href="/pkg/syscall/#SendmsgN"><code>SendmsgN</code></a>
+as an alternate version of
+<a href="/pkg/syscall/#Sendmsg"><code>Sendmsg</code></a>
+that returns the number of bytes written.
+</li>
+
 <li>
 On Windows, the <a href="/pkg/syscall/"><code>syscall</code></a> package now
 supports the cdecl calling convention through the addition of a new function

コアとなるコードの解説

上記の差分は、doc/go1.3.htmlファイルに以下のHTMLスニペットを追加していることを示しています。

<li>
The <a href="/pkg/syscall/"><code>syscall</code></a> package now provides
<a href="/pkg/syscall/#SendmsgN"><code>SendmsgN</code></a>
as an alternate version of
<a href="/pkg/syscall/#Sendmsg"><code>Sendmsg</code></a>
that returns the number of bytes written.
</li>

これは、Go 1.3のリリースノートの「Minor changes to the library」セクションに、syscallパッケージの変更点としてSendmsgNの追加を記述するものです。具体的には、syscallパッケージがSendmsgNを提供し、それがSendmsgの代替バージョンであり、書き込まれたバイト数を返すことを説明しています。これにより、Go 1.3のユーザーは、この新しい機能が利用可能になったことを公式ドキュメントで確認できるようになります。

この変更自体はGoのランタイムコードやライブラリの動作を変更するものではなく、単にドキュメントを更新するものです。しかし、公式ドキュメントに記載されることで、新しいAPIの存在が広く知られ、開発者がその機能を活用できるようになるため、非常に重要な変更と言えます。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント (pkg.go.dev)
  • Go言語のリリースノート (go.dev/doc/)
  • sendmsgシステムコールに関する一般的な情報源 (例: man sendmsg)
  • Web検索結果 (Go syscall Sendmsg SendmsgN)