0

fork、execを使用してperlでAndroidエミュレーターを起動しようとしています。その後、私もそれを殺す必要がありますが、それを殺すと、エミュレーターがバックグラウンドで実行されているゾンビプロセスが発生します。

kill -1だけでなく、を使って殺してみました。また、明示的な exec("exec command ...") を追加して実行しようとしましたが、どちらの方法でも、perl スクリプトが実行されるまでゾンビプロセスが発生します。kill -9killall -v emulator

これが私のコードです:

my $CMD;
my $PID;

sub waitkey()
{
    local( $| ) = ( 1 );
    print "Press <Enter> or <Return> to continue: ";
    my $resp = <STDIN>;
}


$|++;

$CMD = "emulator -avd audit -no-snapshot-save";
# $CMD = "exec emulator -avd audit -no-snapshot-save";

$PID = fork();
if ($PID==0) 
{
    print "forked!\n\n";
    sleep(1);
    exec("$CMD");
    die "Unable to execute";
}

print "PID: $PID\n\n";

sleep(1);
print "------ Processes before killing -----\n";
print `ps aux | grep emulator`;
print "------ Press a key to kill -----\n\n"

&waitkey;
# `kill -1 $PID`;
`kill -9 $PID`;

print "------ Processes after killing -----\n";
sleep(1);
print `ps aux | grep emulator`;


print "----- waiting ... -----\n";
#-- do somehing here with assumption that emulator has been killed --
&waitkey;

私が見る出力で

------ Processes before killing -----
qureshi  10561  0.0  0.0   3556   980 pts/5    S+   13:28   0:00 emulator -avd audit -no-snapshot-save
qureshi  10562  0.0  0.0   4396   616 pts/5    S+   13:28   0:00 sh -c ps aux | grep emulator
qureshi  10564  0.0  0.0  13580   928 pts/5    S+   13:28   0:00 grep emulator

そしてプロセスを殺した後

------ Processes after killing -----
qureshi  10561 30.0  0.0      0     0 pts/5    R+   13:28   0:01 [emulator64-arm]
qureshi  10619  0.0  0.0   4396   612 pts/5    S+   13:28   0:00 sh -c ps aux | grep emulator
qureshi  10621  0.0  0.0  13580   932 pts/5    S+   13:28   0:00 grep emulator

どうすればゾンビプロセスを取り除くことができますか?

4

2 に答える 2

5

ゾンビは、親プロセスが来て終了ステータスを収集するのを待っているプロセス テーブル エントリです。perldoc forkに記載されているように、

子供たちを待たずに分岐すると、ゾンビが蓄積します。一部のシステムでは、 $SIG{CHLD} を "IGNORE" に設定することでこれを回避できます。

設定$SIG{CHLD}は、Linux を含むほとんどの UNIX タイプのシステムで機能するため、お子様が安心して休むように手配する最も簡単な方法です。

ところで、プレフィックスを使用してユーザー定義関数を呼び出すこと&は、Perl 4-ism です。現在の Perl バージョンでは、の代わりにwaitkeyまたはを使用する必要があります。waitkey()&waitkey

于 2013-03-19T10:20:31.097 に答える
4

waitpid子プロセスを強制終了した後、親プロセスで使用する必要があります。これは、新しいプロセスを取得するために使用するためですfork。Perl は のようにクリーンアップ ジョブを実行しませんsystem。しかし、私は CPANのより良いモジュールをお勧めします。これは面倒なこと全体を行います。非常に便利だと思います。

于 2013-03-19T08:43:09.273 に答える