Fork システム コールは、Linux および Unix システムで新しいプロセスを作成するために使用されます。 子プロセス 、fork() 呼び出しを行うプロセス (親プロセス) と同時に実行されます。新しい子プロセスが作成されると、両方のプロセスが fork() システム コールに続いて次の命令を実行します。
子プロセスは、親プロセスで使用するものと同じ pc (プログラム カウンタ)、同じ CPU レジスタ、および同じオープン ファイルを使用します。パラメーターは取らず、整数値を返します。
以下は、fork() によって返されるさまざまな値です。
- 負の値 : 子プロセスの作成に失敗しました。
- ゼロ : 新しく作成した子プロセスに戻ります。
- 正の値 : 親または呼び出し元に返されます。値には、新しく作成された子プロセスのプロセス ID が含まれます。

注記: fork() はスレッドベースの関数であり、正しい出力を取得するには、ローカル システムでプログラムを実行します。
上記のプログラムは Windows 環境ではコンパイルできないことに注意してください。
C の fork() の例
C
c 文字列の配列
#include> #include> #include> int> main()> {> > >// make two process which run same> >// program after this instruction> >pid_t p = fork();> >if>(p<0){> >perror>(>'fork fail'>);> >exit>(1);> >}> >printf>(>'Hello world!, process_id(pid) = %d
'>,getpid());> >return> 0;> }> |
>
>出力
Hello world!, process_id(pid) = 31 Hello world!, process_id(pid) = 32>
例 2: hello が出力される回数を計算します。
C
#include> #include> #include> int> main()> {> >fork();> >fork();> >fork();> >printf>(>'hello
'>);> >return> 0;> }> |
>
>出力
hello hello hello hello hello hello hello hello>
説明
「hello」が出力される回数は、作成されたプロセスの数と同じです。プロセスの合計数 = 2nここで、n は fork システム コールの数です。したがって、ここでは n = 3, 23= 8 3 つの行にいくつかのラベル名を付けてみましょう。
fork (); // Line 1 fork (); // Line 2 fork (); // Line 3 L1 // There will be 1 child process / // created by line 1. L2 L2 // There will be 2 child processes / / // created by line 2 L3 L3 L3 L3 // There will be 4 child processes // created by line 3>
したがって、合計 8 つのプロセス (新しい子プロセスと 1 つの元のプロセス) があります。プロセス間の関係をツリー階層として表現したい場合は、次のようになります。 メインプロセス: P0 1 番目のフォークによって作成されたプロセス: P1 2 番目のフォークによって作成されたプロセス: P2、P3 3 番目のフォークによって作成されたプロセス: P4、P5、P6、P7
P0 / | P1 P4 P2 / P3 P6 P5 / P7>
例 3: 次のプログラムの出力を予測します。
C
#include> #include> #include> #include> void> forkexample()> {> >pid_t p;> >p = fork();> >if>(p<0)> >{> >perror>(>'fork fail'>);> >exit>(1);> >}> >// child process because return value zero> >else> if> ( p == 0)> >printf>(>'Hello from Child!
'>);> > >// parent process because return value non-zero.> >else> >printf>(>'Hello from Parent!
'>);> }> int> main()> {> >forkexample();> >return> 0;> }> |
>
>出力
Hello from Parent! Hello from Child!>
注記: 上記のコードでは、子プロセスが作成されます。 fork() は、子プロセスでは 0 を返し、親プロセスでは正の整数を返します。ここでは、親プロセスと子プロセスが同時に実行されているため、2 つの出力が可能です。したがって、OS が最初に親プロセスに制御を与えるのか、それとも子プロセスに制御を与えるのかはわかりません。
親プロセスと子プロセスは同じプログラムを実行していますが、それはそれらが同一であることを意味するわけではありません。 OS はこれら 2 つのプロセスに異なるデータと状態を割り当て、これらのプロセスの制御フローは異なる場合があります。次の例を参照してください。
例 4: 次のプログラムの出力を予測します。
C
VLCでYouTubeビデオをダウンロード
#include> #include> #include> #include> > void> forkexample()> {> >int> x = 1;> >pid_t p = fork();> >if>(p<0){> >perror>(>'fork fail'>);> >exit>(1);> >}> >else> if> (p == 0)> >printf>(>'Child has x = %d
'>, ++x);> >else> >printf>(>'Parent has x = %d
'>, --x);> }> int> main()> {> >forkexample();> >return> 0;> }> |
>
>出力
Javaでのインスタンス化
Parent has x = 0 Child has x = 2>
または
出力
Child has x = 2 Parent has x = 0>
ここで、2 つのプロセスのデータ/状態は異なるため、1 つのプロセスでのグローバル変数の変更は他の 2 つのプロセスには影響しません。また、親と子が同時に実行されるため、2 つの出力が可能です。
fork() と exec()
fork システムコールは新しいプロセスを作成します。 fork() によって作成される新しいプロセスは、戻り値を除いて現在のプロセスのコピーです。一方、exec() システムコールは、現在のプロセスを新しいプログラムに置き換えます。
C fork() に基づく問題
1. プロセスは次のコードを実行します。
C
for> (i = 0; i fork();> |
>
>
作成される子プロセスの総数は次のとおりです。 (ゲート-CS-2008)
(A)n
(B) 2^n – 1
(C) 2^n
(D) 2^(n+1) – 1
解決策については、これを参照してください。
2. 次のコード部分を考えてみましょう。
C
if> (fork() == 0) {> >a = a + 5;> >printf>(>'%d, %d
'>, a, &a);> }> else> {> >a = a –5;> >printf>(>'%d, %d
'>, a, &a);> }> |
>
>
u、v を親プロセスによって出力される値、x、y を子プロセスによって出力される値とする。次のうち正しいのはどれですか? (ゲート-CS-2005)
(A) u = x + 10 および v = y
(B) u = x + 10 および v != y
(C) u + 10 = x および v = y
(D) u + 10 = x および v != y
文字列.部分文字列Java
解決策については、これを参照してください。
3. 以下のプログラムの出力を予測します。
C
#include> #include> int> main()> > >fork();> >fork() && fork()> |
>
>
解決策についてはこれを参照してください
関連記事 :
- fork() と Pipe() をデモする C プログラム
- C のゾンビおよび孤立プロセス
- fork() とそれを使用して作成されたメモリ共有白黒プロセス