スプライス(システム呼び出し)

ウィキペディアから、無料の百科事典
ナビゲーションにジャンプ 検索にジャンプ

splice()は、ユーザースペースへのラウンドトリップなしでファイル記述子とパイプの間でデータを移動するLinux固有のシステムコールです。関連するシステムコールvmsplice()は、パイプとユーザースペースの間でデータを移動またはコピーします。理想的には、スプライスとvmspliceはページを再マッピングすることで機能し、実際にはデータをコピーしないため、 I/Oパフォーマンスが向上する可能性があります。線形アドレスは必ずしも連続した物理アドレスに対応するわけではないため、これはすべての場合およびすべてのハードウェアの組み合わせで可能であるとは限りません。

仕組み

splice()を使用すると、ユーザースペースからカーネルスペースへのコピーを発生させることなく、あるファイル記述子から別のファイル記述子にデータを移動できます。これは通常、システムセキュリティを強化し、プロセスがファイルを読み書きするためのシンプルなインターフェイスを維持するために必要です。splice()は、パイプバッファを使用して機能します。パイプバッファは、ユーザースペースプロセスに対して不透明なカーネル内メモリバッファです。ユーザープロセスは、ソースファイルの内容をこのパイプバッファーにスプライスしてから、パイプバッファーを宛先ファイルにスプライスできます。すべて、ユーザースペースを介してデータを移動する必要はありません。

Linus Torvaldsは、 KernelTrapの記事に含まれている2006年の電子メールでsplice()について説明しました。[1]

起源

Linuxスプライスの実装は、1998年のLarry McVoyによる元の提案からいくつかのアイデアを借りています。 [2]スプライスシステムコールは、Linuxカーネルバージョン2.6.17で最初に登場し、JensAxboeによって作成されました。

プロトタイプ

 ssize_t splice int fd_in loff_t * off_in int fd_out loff_t * off_out size_t len unsigned int flags );             

関心のあるいくつかの定数は次のとおりです。

/ *スプライスフラグ(まだ石に置かれていません)。* /
#ifndef SPLICE_F_MOVE 
#define SPLICE_F_MOVE 0x01 
#endif 
#ifndef SPLICE_F_NONBLOCK 
#define SPLICE_F_NONBLOCK 0x02 
#endif 
#ifndef SPLICE_F_MORE #define 
SPLICE_F_MORE 0x04 
#endif 
#ifndef 
SPLICE_F

これは、動作中のスプライスの例です。

/*ディスクからログに転送します。* /
int log_blocks struct log_handle * handle int fd loff_t offset size_t size            
{{
    int filedes [ 2 ];  
    int ret ; 
    size_tto_write =サイズ; _   
    ret =パイプfiledes );   
    if ret < 0    
        goto out ; 
    / *ファイルをパイプに接続します(カーネルメモリ内のデータ)。* /
    while to_write > 0 {    
        ret = splice fd offset filedes [ 1 ]、NULL to_write         
                SPLICE_F_MORE | SPLICE_F_MOVE );  
        if ret < 0    
            後藤パイプ; 
        そうしないと
            to_write- = ret ;  
    }
    to_write =サイズ;  
    / *パイプ(カーネルメモリ内)のデータをファイルに接続します。* /
    while to_write > 0 {    
        ret = splice filedes [ 0 ]、NULL handle- > fd       
                ハンドル-> fd_offset )、to_write  
                SPLICE_F_MORE | SPLICE_F_MOVE );  
        if ret < 0    
            後藤パイプ; 
        そうしないと
            to_write- = ret ;  
    }

パイプ
    close filedes [ 0 ]);  
    close filedes [ 1 ]);  
アウト
    if ret < 0    
        return - errno ; 
    0を返す; 
}

補完的なシステムコール

splice()は、 splice()アーキテクチャを完成させる3つのシステムコールの1つです。vmsplice()は、アプリケーションデータ領域をパイプに(またはその逆に)マップできるため、sys_splice()がファイル記述子とパイプの間で転送するパイプとユーザーメモリ間の転送が可能になります。tee()は三部作の最後の部分です。あるパイプを別のパイプに複製し、アプリケーションがパイプに接続される方法でフォークを有効にします。

要件

ソケットでsplice()を使用する場合、ネットワークコントローラー(NIC)はDMAをサポートする必要があります。そうでない場合、splice()はパフォーマンスを大幅に向上させることはできません。これは、パイプの各ページがフレームサイズ(1ページあたり使用可能な4096バイトの1460バイト)までいっぱいになるためです。

すべてのファイルシステムタイプがsplice()をサポートしているわけではありません。また、AF_UNIXソケットはsplice()をサポートしていません

も参照してください

参照

  1. ^ 「Linux:splice()とtee()の説明」kerneltrap.org。2006-04-21。2013年5月21日にオリジナルからアーカイブされまし2014年4月27日取得
  2. ^ 「アーカイブされたコピー」2016-03-04にオリジナルからアーカイブされました2016年2月28日取得{{cite web}}:CS1 maint:タイトルとしてアーカイブされたコピー(リンク

外部リンク