Cでのフォークシステムコール

Fork System Call C



fork()システムコールは、Cプログラムで子プロセスを作成するために使用されます。 fork()は、アプリケーションで並列処理が必要な場合に使用されます。 fork()システム関数はヘッダーで定義されています sys / types.hunistd.h 。 forkを使用するプログラムでは、wait()システムコールも使用する必要があります。 wait()システム呼び出しは、子プロセスが終了するのを親プロセスで待機するために使用されます。子プロセスを終了するために、exit()システム呼び出しが子プロセスで使用されます。 wait()関数はヘッダーで定義されています sys / wait.h そしてexit()関数はヘッダーで定義されています stdlib.h

図1:基本的なfork()ワークフロー

図1:基本的なfork()ワークフロー







この記事では、fork()システムコールを使用してCで子プロセスを作成する方法を紹介します。それでは、始めましょう。



fork()構文と戻り値:

fork()システム関数の構文は次のとおりです。



pid_tフォーク((空所)。;

fork()システム関数は引数を受け入れません。タイプの整数を返します pid_t





成功すると、fork()は0より大きい子プロセスのPIDを返します。子プロセス内では、戻り値は0です。fork()が失敗した場合は、-1を返します。

単純なfork()の例:

簡単なfork()の例を以下に示します。



#含む
#含む
#含む
#含む
#含む

int主要((空所)。 {{
pid_t pid=フォーク(()。;

もしも((pid== 0)。 {{
printf (('子=> PPID:%d PID:%dNS'getppid(()。getpid(()。)。;
出口 ((EXIT_SUCCESS)。;
}
そうしないと もしも((pid>> 0)。 {{
printf (('親=> PID:%dNS'getpid(()。)。;
printf (('子プロセスが終了するのを待っています。NS')。;
待つ((ヌル)。;
printf (('子プロセスが終了しました。NS')。;
}
そうしないと {{
printf (('子プロセスを作成できません。NS')。;
}

戻るEXIT_SUCCESS;
}

ここでは、fork()を使用して、メイン/親プロセスから子プロセスを作成しました。次に、子プロセスと親プロセスからPID(プロセスID)とPPID(親プロセスID)を印刷しました。親プロセスでは、wait(NULL)を使用して、子プロセスが終了するのを待ちます。子プロセスでは、exit()を使用して子プロセスを終了します。ご覧のとおり、親プロセスのPIDは子プロセスのPPIDです。だから、子プロセス 24738 親プロセスに属します 24731

関数を使用して、プログラムをよりモジュール化することもできます。ここで、私は使用しました processTask()parentTask() それぞれ子プロセスと親プロセスの関数。これがfork()が実際に使用される方法です。

#含む
#含む
#含む
#含む
#含む

空所childTask(()。 {{
printf (('こんにちは世界NS')。;
}

空所parentTask(()。 {{
printf (('主な任務。NS')。;
}

int主要((空所)。 {{
pid_t pid=フォーク(()。;

もしも((pid== 0)。 {{
childTask(()。;
出口 ((EXIT_SUCCESS)。;
}
そうしないと もしも((pid>> 0)。 {{
待つ((ヌル)。;
parentTask(()。;
}
そうしないと {{
printf ((「子プロセスを作成できません。」)。;
}

戻るEXIT_SUCCESS;
}

上記のプログラムの出力:

fork()とループを使用して複数の子プロセスを実行する:

ループを使用して、必要な数の子プロセスを作成することもできます。以下の例では、forループを使用して5つの子プロセスを作成しました。また、子プロセスからPIDとPPIDを印刷しました。

#含む
#含む
#含む
#含む
#含む

int主要((空所)。 {{
にとって((int= 1;<= 5;++)。 {{
pid_t pid=フォーク(()。;

もしも((pid== 0)。 {{
printf (('子プロセス=> PPID =%d、PID =%dNS'getppid(()。getpid(()。)。;
出口 ((0)。;
}
そうしないと {{
printf (('親プロセス=> PID =%dNS'getpid(()。)。;
printf (('子プロセスが終了するのを待っています...NS')。;
待つ((ヌル)。;
printf (('子プロセスが終了しました。NS')。;
}
}

戻るEXIT_SUCCESS;
}

ご覧のとおり、親プロセスIDはすべての子プロセスで同じです。したがって、それらはすべて同じ親に属します。また、線形に実行されます。次々と。子プロセスの制御は高度なタスクです。 Linuxシステムプログラミングとその仕組みについて詳しく学ぶと、これらのプロセスのフローを好きなように制御できるようになります。

実際の例:

md5、sha256などのハッシュ生成などのさまざまな複雑な数学的計算には、多くの処理能力が必要です。メインプログラムと同じプロセスでそのようなことを計算する代わりに、子プロセスでハッシュを計算して、ハッシュをメインプロセスに返すことができます。

次の例では、子プロセスで4桁のPINコードを生成し、それを親プロセスであるメインプログラムに送信しました。次に、そこからPINコードを印刷しました。

#含む
#含む
#含む
#含む
#含む

intgetPIN(()。 {{
// PPIDとPIDをシードとして使用します
srand ((getpid(()。 +getppid(()。)。;
int秘密の= 1000 + (()。 9000;
戻る秘密の;
}

int主要((空所)。 {{
intfd[2];
パイプ((fd)。;
pid_t pid=フォーク(()。;

もしも((pid>> 0)。 {{
選ぶ((0)。;
選ぶ((fd[1])。;
((fd[0])。;

intsecretNumber;
size_treadBytes=読んだ((fd[0] secretNumber のサイズ((secretNumber)。)。;

printf (('PINを待っています...NS')。;
待つ((ヌル)。;
printf (('読み取られたバイト数:%ldNS'readBytes)。;
printf (('ピン:%dNS'secretNumber)。;
}
そうしないと もしも((pid== 0)。 {{
選ぶ((1)。;
選ぶ((fd[0])。;
((fd[1])。;

int秘密の=getPIN(()。;
書きます((fd[1] 秘密の のサイズ((秘密の)。)。;
出口 ((EXIT_SUCCESS)。;
}

戻るEXIT_SUCCESS;
}

ご覧のとおり、プログラムを実行するたびに、異なる4桁のPINコードを取得します。

つまり、これが基本的にLinuxでfork()システムコールを使用する方法です。この記事を読んでくれてありがとう。