2013-03-19 2 views
0

Я пытаюсь запустить эмулятор Android в Perl, используя fork, exec. Впоследствии мне нужно убить его, но убить его приводит к процессам зомби с эмулятором, работающим в фоновом режиме.Perl fork(), exec(), а затем убить создание процесса зомби

Я пробовал убивать, используя kill -1, а также kill -9 и killall -v emulator. Я также попробовал exec'ing, добавив явный exec («exec command ...»), но в любом случае я получаю зомби-процесс до запуска скрипта perl.

Вот мой код:

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

Вы должны использовать waitpid в родительском процессе после убийства дочернего процесса. Это потому, что вы используете fork, чтобы получить новый процесс, Perl не выполнил бы работу по очистке для вас, как в system. Но я рекомендую a better module в CPAN, который делает всю беспорядочную вещь, я нахожу ее очень удобной.

5

Зомби - это всего лишь запись в таблице процессов, которая ждет, когда родительский процесс зайдет и получит статус выхода. Как указано в perldoc fork,

Если вы вилка никогда не ждет ваших детей, вы будете накапливать зомби. В некоторых системах вы можете избежать этого, установив $ SIG {CHLD} в "IGNORE".

Установка $SIG{CHLD} работы на большинстве систем Unix-типа, в том числе Linux, так что бы самый простой способ организовать для своих детей, чтобы отдохнуть в мире.

BTW, вызывающий пользовательские функции с префиксом & является Perl 4-ism. В текущих версиях Perl вы должны использовать только waitkey или waitkey() вместо &waitkey.

Смежные вопросы