2017-05-17 5 views
2

学習目的のために、私はゾンビプロセスを生成するコードを書いた。私の仮定でExit()を呼び出すがゾンビにならない子プロセス

#include <sys/types.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

pid_t pid; 

int main() { 
    pid = fork(); 
    if (pid == 0) { 
    exit(0); 
    } else { 
    printf("the child process is %d", pid); 
    sleep(20); 
    } 
} 

、上記のコードは、このような方法で動作する必要があります:ここにコードされた子プロセスは、ステータスコード0と0のpidexitを受け取るには、親プロセスは子プロセスのpidを受け取り、それをプリントアウトして20秒間スリープ状態になります。子プロセスがexitのときは、親プロセスがwaitを呼び出さないため、子プロセスは約20秒間ゾンビでなければなりません。

しかし、コードを実行すると、約20秒間待機して、子プロセスのpidを出力します。 20秒で、ゾンビプロセスとしてps -lに子プロセスが表示されません。

コードの理解と実際の動作の違いは何ですか?

P.S.私はMac OS Sierraを使用しています。

+2

printfに新しい行 "\ n"を追加してみてください。stdoutはバッファされています。 – technosaurus

+0

"\ n"を追加するとメッセージを印刷できます。ありがとうございます!しかし、子プロセスはまだゾンビにはならない。 – Musen

答えて

-1

「子プロセスはps -lではゾンビプロセスとして表示されません」とはどういう意味ですか?あなたは代わりにどのような状態を見ますか?それとも最初に子供が見えないということでしょうか?明確にするには、 "ps 1234"(または取得したpid)を実行してプロセスを検査することができます。

#include <sys/types.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

pid_t pid; 

なぜグローバルですか。

int main() { 

int(void)である必要があります。

pid = fork(); 
    if (pid == 0) { 
    exit(0); 

「終了時」ハンドラの呼び出しを避けるには、_Exitにする必要があります。このおもちゃの例では重要ではありませんが、誤った習慣を育てる理由はありません。

} else { 
    printf("the child process is %d", pid); 
    sleep(20); 

代わりにpause()またはgetchar()を使用できます。

} 
} 
+0

'_exit()'を呼び出すのは良い習慣ですか?何? exitハンドラをインストールする理由は何ですか? 40年以上のプログラミング経験の中でこれが初めて聞こえます。 8/ –

+0

子供には一般的ではありません。それはそれらを複数回呼び出さないことです。 –

+0

良い習慣は、あなたのプログラムで常に行うことです。 'exit()'の代わりに '_exit()'を呼び出すのは良い習慣ではありません**。私は馬鹿だから、ファイルを閉じたり、状態を保存することはできません。ライブラリはそれを利用するので、出口ハンドラの実行を許可するのが良い習慣です。 2つのプロセスがあるので、すべてのライブラリの実行環境のインスタンスが2つあるため、at exitハンドラはおそらく両方で実行する必要があります。 'atexit()'ハンドラのインストーラは、ハンドラをインストールする前にそれを考慮する必要があります。 –

0

2つの問題があります。 1つは、printf文字列の最後に改行(\n)がないことです。 stdoutはバッファされた行なので、改行を出力するか、明示的にストリームをフラッシュしない限り、出力は出力バッファからフラッシュされません。

だから、改行を追加して、それがすぐに印刷する必要があります:

printf("the child process is %d\n", pid); 

あなたは子のpidが表示されない主な理由は、あなたがpsコマンドを使用しているどのように関係しています。このコードを実行するシェルと異なるシェルからpsを呼び出すと仮定すると、ps -lはコマンドを実行しているセッションのプロセスのみを表示します。したがって、他のセッション/シェルから開始されたプロセスは表示されません。

オプション(つまりps -elまたはps -ef)を使用すると、システム内のプロセスの完全な一覧が表示されます。その後、ゾンビのプロセスを見ることができるはずです。

0

明日までMAC OSシステムにアクセスすることはできませんが、プログラムはLinuxシステムでゾンビプロセスを作成します。私は、親プロセスが終了したときにメッセージを追加するには、サンプルコードを変更した、とすでに適切にラインを終了し、printf()呼び出しの時点で出力を生成する\n文字のコメント:

zombie.cを

#include <sys/types.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

pid_t pid; 

int main() { 
    pid = fork(); 
    if (pid == 0) { 
    exit(0); 
    } else { 
    printf("the child process is %d\n", pid); 
    sleep(20); 
    printf("exit();\n"); 
    } 
} 

とLinuxでの出力は次のようになります。FreeBSDで

$ zombie & 
[1] 5781 
the child process is 5786 

$ ps 
    PID TTY   TIME CMD 
2569 pts/0 00:00:00 bash 
5781 pts/0 00:00:00 zombie 
5786 pts/0 00:00:00 zombie <defunct> <-- this is the zombie. 
5795 pts/0 00:00:00 ps 

$ exit(); <-- zombie program finishing. 

(およびMAC OSはそれに非常によく似ている)のものは、と行く:

$ zombie & 
[1] 7326 
the child process is 7329 
$ ps 
    PID TT STAT  TIME COMMAND 
7281 0 Ss  0:00,18 -bash (bash) 
7326 0 S  0:00,02 zombie 
7329 0 Z  0:00,00 <defunct> <-- this is the zombie. 
7335 0 R+  0:00,01 ps 
$ exit(); <-- zombie program finishing. 

明日は、Mac OS Xシステムで同じことをやり遂げることができ、ゾンビプロセスを作成する第3のシステムを組み込むことができます。

+0

ありがとう!実際には 'ps child_id'はゾンビプロセスを表示しますが、' ps'だけでは表示されません。 – Musen

関連する問題