9
#include <stdio.h>
int num = 0;
int main(int argc, char*argv[]){
    int pid;
    pid = fork();
    printf("%d", num);  
    if(pid == 0){       /*child*/
        num = 1;
    }else if(pid > 0){  /*parent*/
        num = 2;
    }
    printf("%d", num);
}

可能な出力が0102または0012または0201または0021になる理由を理解するのに問題があります。

これが私が(考えて)作成すべきものです。これは最初のprintfステートメントにヒットし、どの子または親が最初に実行されても、numは変更されていないため、最初に0になります。次に、nextは1または2のいずれかであり、次のプロセスが実行されるため、再び0(親からコピー)で開始し、次に1または2のいずれかで開始します。したがって、可能な出力は次のようになります。

0101または0102または0201または0202

4

2 に答える 2

10

親と子の両方で、最初のnumは0ですprintf。親と子の両方で、0が出力され、その後に他の値が続きます。親プロセスでは、他の値は2です。子プロセスでは、他の値は1です。

ただし、注意すべき重要な点は、各プロセスには、他の番号の前にゼロを印刷する必要があるという強制的な順序がありますが、2つのプロセスの相互の印刷に制限はないということです。

これが実際の例えです。同僚と私が同時に仕事を辞め、食料品店に立ち寄ってから家に帰るとします。私は家に帰る前に店にいたこと、そして彼が家に帰る前に食料品店にいたことを知っています。しかし、誰が最初に食料品店にいたのか、誰が最初に家にいたのかはわかりません。それぞれが同じ時間に食料品店に到着し、次にそれぞれが同じ時間に帰宅する可能性があります。あるいは、彼が遅れて、彼が店に着く前に食料品店と家に帰る可能性があります。

起こらないことは、1つまたは2つを複数回印刷することです。返品後fork、概念的に同時に2つのプロセスが実行され、それらのイベントの相対的なタイミングは指定されていませんが、各プロセスのイベントの順序は明確に定義されています。各プロセスはnum、再度印刷する前に1または2に設定されますfork。また、子で0を返し、親で子のpidを返すように定義されているため、それぞれ異なる値に設定されます。

実際には、別の妥当な出力があります00。新しいプロセスを作成できない場合forkは、-1を返します。この場合、プログラムはを出力し、-1は0でも0よりも大きくないため0ifおよびsは失敗し、numは変更されず、プログラムは再度出力します。else if0

Cプログラムでの効果の順序の定義について多くを学びたい場合、検索するキーワードは「シーケンスポイント」です。このプログラムでは、(2つのコピーを同時に実行しているという事実を除けば)かなり簡単ですが、わかりにくい場合もあります。

于 2013-03-07T04:11:27.657 に答える
9

これはの問題ではありませんfork()。バッファリングされprintf()ているのでです。printf()通常、バッファは、末尾に改行文字'\n'が見つかったときにフラッシュされます。ただし、これを省略したため、バッファの内容は保持され、フラッシュされません。最終的に、両方のプロセス(元のプロセスと子)には、0または1を含む出力バッファーが含まれます。最終的にフラッシュされると、両方のプロセスでこれが表示されます。

fflush(stdout);後に追加しprintf()て試してください。

于 2013-03-07T04:15:01.347 に答える