3

前奏曲

sendfile()次の 2 つの理由から、非常に便利な syscall です。

まず、/ (ジャイブを好む場合は/ ) ループよりもコードが少なくて済みます。 第二に、前述の方法よりも高速です(システムコールが少ない、実装がバッファなしでデバイス間でコピーされるなど)。read()write()recv()send()

コードが少ない。もっと効率的。素晴らしい。

UNIX では、すべてが (ほとんどの場合) ファイルです。これは、プラトニックな理論と現実世界の実践が衝突した醜い領域です。ソケットは、一部のデバイスに存在するファイルとは根本的に異なることを理解しています。Linux/*BSD/Darwin/OS が実装sendfile()するものは何でも、この特定のシステムコールがソケット (具体的にはストリーミング ソケット) への書き込みに制限されている理由を知るために、ソースを掘り下げていません。

ただ知りたいだけです...

質問

sendfile()宛先ファイル記述子をソケット以外のもの (ディスク ファイルやパイプなど) にすることを制限しているのは何ですか?

4

2 に答える 2

4

これは初期の Linux 2.6 で導入された制限だったことを覚えているようです (2.4 には制限がありませんでした)。

2.6.17 以降、Linux には同様の splice() システム コールがあります。より柔軟ですが、効率はわずかに低下します。Linus は splice() に関して sendfile の再実装について話しました。http://kerneltrap.org/node/6505を参照

于 2009-12-09T22:11:42.020 に答える
3

基本的に、それを制限しているのは「誰もまだコードを書いていない」ということだけです。

ただし、あなたが言及した2つのケースのコードを誰も作成しなかった理由は、どちらもデータをコピーする必要がありsendfile、最初に使用する利点の多くが失われるためだと思います.

  • file-to-filesendfileの場合、コピーが必要になります。そうしないと、同じページがソース ファイルのクリーン ページと宛先ファイルのダーティ ページの両方としてページキャッシュに存在する必要があるためです。現時点では、ページキャッシュがそのケースを処理するように構築されているとは思いません (もちろん、十分な動機があれば、これは変更される可能性があります)。

  • file-to-pipesendfileの場合、宛先プロセスはプライベートで書き込み可能なデータのコピーを取得する必要があるため、コピーが必要です。とにかく、このケースのほとんどの用途では、すでにmmap.

于 2009-12-09T22:52:12.837 に答える