他のインターフェースはありますか?/procファイルシステム?
LinuxカーネルのsyscallAPIはプライマリAPIであり(libcの下に隠されており、プログラマーが直接使用することはめったにありません)、ほとんどの標準IPCメカニズムはすべてがファイルアプローチであり、最終的に読み取り/書き込み(およびそれ以上)の呼び出しが必要になるため、ここではそれらを排除します。
ただし、ほとんどのプラットフォームでは(そこに到達するためにすべてのシステムコールを除外した場合)、次の方法があります: [〜#〜] vdso [〜#〜] 。これは、カーネルが1つ(または複数)のわずかに魔法のページを各プロセスにマップするメカニズムです(通常はELF .soの形式で)。これは、_linux-vdso.so
_またはldd
または_/proc/PID/maps
_と同様に表示されます。これは、カーネルとユーザープロセスの間で効果的にメモリマップされますIPC(現在の実装では一方向ですが)。
これは一般にシステムコールを高速化するために使用され、元々はx86のパフォーマンスの問題に対処するために実装されました( _linux-gate.so
_ )が、カーネルデータやアクセス関数も含まれる場合があります。 getcpu()
やgettimeofday()
のような呼び出しは、actualsyscallとカーネルコンテキストスイッチを作成するのではなく、これらを使用する場合があります。これらの最適化された呼び出しの可用性は、glibcスタートアップコードによって検出および有効化されます(プラットフォームの可用性によって異なります)。現在の実装には、直接読み取ることができる「VVAR」ページと呼ばれる共有カーネル変数の(読み取り専用)ページが含まれています。
_strace -e trace=clock_gettime date
_の出力を調べて、date
コマンドがclock_gettime()
システムコールを実行するかどうかを確認することでこれを確認できますが、VDSOが機能している場合は実行されません(時刻はVDSOページの関数によるVVARSページ。 _Arch/x86/vdso/vclock_gettime.c
_ を参照してください。
ここに役立つ技術的な要約があります: http://blog.tinola.com/?e=5 より詳細なチュートリアル: http://www.linuxjournal.com/content/creating -vdso-colonels-other-chicken 、およびマニュアルページ: http://man7.org/linux/man-pages/man7/vdso.7.html
番号。
些細な反例、これはカーネルと相互作用します:
int main() {
volatile char *silly = 0;
*silly = 'a';
}
これにより、カーネルのページフォールトハンドラーが呼び出され、最終的にプロセスがSIGSEGV
を取得します(Cによる未定義の動作であるため、コンパイラーがそのコードを「最適化」して明白な以外のことを実行しないと想定します)標準では、必ず-O0
)でコンパイルしてください。