システムコールの理解:Linux での目的、機能、および一般的な使用法
この Linuxhint の記事では、システム コールとは何か、その用途、標準 C ライブラリの他の関数との違いについて説明します。また、それらがシステム内のカーネルに対してどのような機能を提供するのか、また、プロセスが提供するサービスをどのように使用するのかについても説明します。また、最も一般的に使用されるシステム コールのリストと、各関数の簡単な説明と、それらが宣言されているヘッダーも示します。別のセクションでは、コマンド コンソールを通じてシステム コールの動作を監視する方法を説明します。
概念的には、すべてのシステムはレイヤーで構成されており、各レイヤーには独自の機能と権限があります。システムを構成するこのレイヤーのスタックは、ハードウェア コンポーネントを含む最下位レベルで始まり、ユーザー モードとして知られる最上位レイヤーで終わります。
コンピューター上で実行するすべてのプログラムとすべてのコードは、システムのユーザー モードで実行されるプロセスで作成して結果をコンパイルします。このモードでは、ユーザーは作業と日常タスクの実行、さまざまなアプリケーションの起動と使用、ファイルの管理などを行います。セキュリティ レベルでは、これはシステムの最も表面的な層であるため、最も制限されており、デフォルトではシステム リソースの直接管理と使用が完全に制限されています。
前述したように、ハードウェア層はシステムの最下位レベルです。そのすぐ上には Linux カーネルがあります。カーネルはオペレーティング システムの中心であり、ハードウェアと統合され、ハードウェアを厳密に管理する権限を有する唯一のカーネルです。たとえば、プロセスとメモリはここで管理され、ハードディスクや SSD からのデータへのアクセス、ネットワーク デバイスの制御などが行われます。OS とプロセスがハードウェアで行うことはすべて、カーネルを通じて行われます。したがって、ソフトウェアとハードウェアを統合した一種のファームウェアであると言えます。
オペレーティング システムがユーザー モードに課すリソースのアクセスと管理の制限を考慮すると、これらのリソースへのアクセスはカーネルを通じてのみ可能であるため、プロセスが機能するために必要なリソースと対話できるメカニズムが不可欠です。
システム コール (SysCall) は、オペレーティング システムによって提供される一連の関数であり、ユーザー プロセスとカーネル間のインターフェイスとして機能します。これらの機能を使用すると、OS と対話し、システム リソースの使用を必要とするサービスを OS 経由で要求できます。システムコールはリソースやその管理への直接アクセスを許可しませんが、カーネルがそれらを管理し、それらを呼び出すプロセスで使用できるようにしますが、常にその厳格な管理下にあります。
実際には、システム コール関数は通常の関数のように見え、そのように実装されます。これらには、処理されるデータが送信される入力引数と、オペレーティング システムが結果を返す出力引数があります。
このタイプの関数を呼び出す方法は、C ライブラリにある他の関数と同じです。したがって、それが呼び出し関数であるかどうかという問題は、実際にはプログラマにとって純粋に概念的な問題です。
これらの関数の引数は、C 言語の標準型を使用します。ただし、タスクの性質上、これらは通常、メモリ アドレス、記述子、パスなどを格納するポインタです。
Linux では、現在約 350 のシステム コールがあります。また、システム コールではありませんが、コード内で syscall を使用してメモリを動的に管理する malloc()、free()、calloc()、realloc() 関数など、システム コールを通じてリソースを管理する関数が多数あります。
Linux コンソールで Strace コマンドを使用してシステム コールを監視する方法
システム コール関数の概要がわかったところで、Linux コマンド コンソールから「strace」コマンドを使用してシステム コール関数をリアルタイムで監視する方法を説明します。 「strace」コマンドは非常に柔軟です。これはシステムを監視するために使用され、次のコマンドで表示できるいくつかのオプションを提供します。
このコマンドを実行すると、「strace」によって提供される監視オプションのリストがコマンド コンソールに表示されます。

プロセスの syscall を監視するには、次のコマンドを使用してプロセスを実行する必要があります。
ストラク
strace ./プロセス
e -h
これをテストするために、「C 言語で関数を接続する」というタイトルの記事で例として示した次のコードをコンパイルします。このコードは非常に単純ですが、HTTP サービスを通じて Google ホストに接続し、コマンドを送信して応答を受信できるようにするため、非常に興味深いものです。
#include
#include <文字列.h>
#include
#include
#include
#include
#include
#include
int main (){
//ステップ1
int ソケット ID;
int ポート =80;
int エラー;
文字バッファ [1025];
構造体 hostent *サーバー;
構造体 sockaddr_in クライアント;
memset(&server, 0, sizeof(server));
//ステップ2
サーバー =gethostbyname ( "www.google.com" );
if(サーバー ==NULL)
{
printf("\nドメイン データの取得中にエラーが発生しました。\n");
1 を返します。
}
//ステップ3
socket_id =ソケット ( AF_INET, SOCK_STREAM, 0 );
//ステップ4
client.sin_family =AF_INET;
client.sin_port =htons(port);
//ステップ5
bcopy((char *) サーバー->h_addr,
(char *) &client.sin_addr.s_addr,
sizeof(server->h_length));
error=connect(socket_id, (struct sockaddr *) &client, sizeof(client));
if (エラー <0){
printf ("\nサーバーへの接続を確立できませんでした\n");
閉じる(ソケットID);
1 を返します。
}
printf ("\n接続先:%s\n", inet_ntoa( client.sin_addr ));
一方 (1){
printf("終了するには Ctrl+c を押してください \nhttp コマンドを送信します:");
fgets(バッファ、1025、標準入力);
send(socket_id, バッファ, 1025, 0);
memset(&buffer, '\0', 1025);
recv(socket_id, バッファ, 1025, 0);
printf("%s", バッファ);
memset(&buffer, '\0', 1025);
}
}
コードをコンパイルし、「connect」出力名を付けます。次に、「./connect」コマンドを使用してこれを実行し、syscall を監視できるように「strace」コマンドを先頭に追加します。
このコマンドは、コマンド コンソールにプロセスの syscall を表示します。次の図に示すように、このコードでは、socket()、connect()、send()、recv() の syscall のみを使用していますが、その実行には、使用する関数のコード内で発生する他のシステム コールが必要です。

次のコマンドは、プロセス終了時のシステム コールの概要を表示します。

プロセス管理用のシステム コール関数:
execlp()
execle()
execv()
execvp()
execvpe()
親プロセスから PID とリソースを継承することによって、あるプロセスを別のプロセスに置き換えるシステム関数呼び出しのファミリー。unistd.hfork()プロセスを複製する。unistd.hgetpid()呼び出しプロセスの PID を取得する。unistd.hgetppid()呼び出しプロセスの親プロセスの PID を取得する。unistd.hexit()プロセスの終了ステータスを報告する。stdlib.hgetcwd()getwd()
呼び出しプロセスの現在の作業ディレクトリを含む文字列を返します。unistd.hpause()シグナルが到着するまでプロセスを一時停止します。unistd.hwait()親プロセスからの子プロセスの出力を待ちます。wait.hファイル管理のためのシステム コール関数:
機能 説明 ヘッダー オープン()openat()
ファイルを開く.fcntl.hclose()ファイルを閉じる.unistd.hread()ファイルを読み取る.unistd.hpoll()特定の操作でファイルの可用性をポーリングする.poll.hwrite()ファイルを書き込む.unistd.hfcntl()ファイル記述子を操作する.fcntl.htruncate()ftruncate()
ファイルを指定した長さに切り詰めるunistd.hcreat()ファイルを作成する.fcntl.hchmod()fchmod()
ファイルのアクセス許可を設定しますsys/stat.hunlink()file.unistd.h を削除しますシグナル処理のためのシステムコール関数:
機能 説明 signal()シグナルをハンドラーにリンクします。signal.hkill()プロセスにシグナルを送信します。signal.hkillpg()プロセスのグループにシグナルを送信します。signal.hraise()シグナルを呼び出すプロセス内でシグナルのアクションを実行します。signal.hsigaction()シグナルのアクションを設定します。signal.hsigwait()指定されたシグナルが到達するまで呼び出しスレッドの実行を一時停止します。到着.signal.hsighold() 呼び出しプロセスのシグナルにシグナルを追加します。 Mask.signal.hsigignore() signal を無視します。signal.hsigblock() signal をブロックします。psiginfo()
signal.signal.h の説明を含むメッセージを出力します。ソケット処理のためのシステムコール関数:
機能 説明 socket()socket.socket.hbind()を作成します。ソケットに名前をバインドします。socket.hconnect()socket.socket.hlisten()を接続します。socket.haccept()socket.hrecv()で接続を受け入れます。recvfrom()
recvmsg()
メッセージをsocket.socket.hsend()から受信します。sendto()
sendmsg()
ソケットからメッセージを送信します。socket.hgetsockname()記述子によって特定のソケットのアドレスを返します。socket.hgetsockopt()socket.socket.h のオプションを設定または取得します結論
この Linuxhint の記事では、システム コール関数とは何か、またシステム リソースの使用を伴うカーネル サービスを要求するためにそれらがどのように使用されるかについて説明しました。ユーザー プロセスが何であるか、およびシステム コールを介してユーザー プロセスがカーネルとどのように対話するかについて簡単に説明しました。
これらの機能をすぐに実践できるように、最も一般的に使用されるシステム コールのリストと、それらを使用するためにコードに含める必要がある簡単な説明およびヘッダーが含まれています。コマンド コンソールを介してプロセスの syscall を監視する方法を説明したセクションも追加しました。
-
Cプログラムの3Dでの2つの平面間の角度?
ここでは、3次元空間内の2つの平面間の角度を計算する方法を説明します。平面はP1とP2です。以下のような円周率の方程式- 角度が「A」の場合、このルールに従います- 例 #include <iostream> #include <cmath> using namespace std; class Plane{ private: double a, b, c, d; public: Plane(double a = 0, do
-
Cプログラムで六角形に内接する円に内接する正方形の面積は?
ここでは、1つの円に内接し、その円が六角形に内接する正方形の領域が表示されます。正方形の側面は「a」です。円の半径は「r」で、六角形の辺は「A」です。図は次のようになります。 六角形に内接する円の半径は-であることがわかっています。 また、円の半径は正方形の対角線の半分です。だから- それなら、次のように言うことができます- その場合、面積は- 例 #include <iostream> #include <cmath> using namespace std; float area(float A) { //A is the side o