4

私はこの声明を理解する必要があります:

if (fork() && !fork())

それは常に偽であるべきではありませんか?つまり、私が書くと:

if (a && !a)

それは常に false なので、最初のものも常に false である必要があります。間違っていますか? もちろんそうですが、誰かがこの奇妙なことを説明してくれることを願っています。

私は試験のために C を勉強していて、このコードを解決しなければなりませんでした:

int main(){
if(fork && !fork()){
   printf("a\n");
}
else printf("b\n");
}
4

5 に答える 5

8

UNIX プロセス作成システム コール fork() を呼び出すたびに、2 回返されます。まず子のPIDを親(fork()を呼んだプロセス)に返します。次に、新しく作成された子に 0 に戻ります。

マニュアルページから:

戻り値

成功すると、子プロセスの PID が親に返され、0 が子に返されます。失敗すると、親に -1 が返され、子プロセスは作成されず、errno が適切に設定されます。

あなたの場合

if (fork() && !fork())

内のステートメントはif、fork を 2 回呼び出します。したがって、何が起こるかは次のとおりです。

A
|----------------B
|                |
|---C            |
|   |            |         

への最初の呼び出しfork()は、A と B の両方で返されます。A では非ゼロになり、B ではゼロになります。

fork() の 2 回目の呼び出しは A からのみ呼び出されます。最初の fork が B に 0 を返したため、2 回目の呼び出しは行われませんfork()これは、最初のオペランドがゼロ以外の場合に評価を短絡するためです。&&これを指摘してくれたダニエルに感謝します。

したがって、これから表を作成できます。

PID       fork()1      fork()2
------------------------------
A           >0          >0
B           =0          >0
C           >0          =0

したがって、チャートから、プロセス CはTRUEifと評価されます。

fork()1C に戻らなかったことを覚えておくことが重要です。親から既に評価された式のコピーを取得しました。

これがあなたの質問を説明することを願っています。

于 2012-07-10T20:24:22.967 に答える
6

まず、関数です。常に同じ値を返すとは限りません。

この場合、具体的には、フォークは別のプロセスを作成する関数です。元のプロセスは(子のpidの)正の戻り値を取得し、子プロセスは0の戻り値を取得します。

コードには、合計3つのプロセスが含まれることになります。ifステートメントは、そのうちの1つについてtrueと評価されます(以下のプロセスC)。

     A
     |__________B
     |          |
     |__C       |
     |  |       |       
     |  |       |        
于 2012-07-10T20:05:06.097 に答える
3
shouldn't be always false?

いいえ。

これは変数ではないため、を呼び出すたびfork()に新しい子プロセスが作成されます。

于 2012-07-10T20:00:21.847 に答える
1

を呼び出すfork()たびに、各プロセスに 1 つずつ、合計 2 つの値が返されます。したがって、決定ごとに、各パスをたどる 1 つのプロセスがあります。

于 2012-07-10T20:02:40.340 に答える
0

関数呼び出しはfork()、子プロセスに 0 を返し、親プロセスにプロセス ID を返します。基本的に、これが行うことは一度フォークすることです。プロセスが親の場合、次のブロックにジャンプし、子プロセスが再びフォークします。このプロセスの親は次のブロックにジャンプし、このブロックの子はifステートメントのコードを実行します。

于 2012-07-10T20:07:38.303 に答える