2015-07-27 3 views
0

Я развожу ребенка и пытаюсь его убить.Не удалось убить процесс fork'ed

pid_t *child_pid; 

int main(){ 
    child_pid = mmap(NULL, sizeof(pid_t), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);$ 

    int a = fork(); 
    if (a != 0) { 
      printf("child @ %d\n", a); 
      *child_pid = a; 
      system("sleep 100"); 
    } else { 
      sleep(1); 
      printf("Trying to kill %d\n", *child_pid); 
      int ret = kill(*child_pid,SIGKILL); 
      printf("killled with %d\n", ret); 
    } 
} 

Однако команда убить застревает на:

child @ 4752 
Trying to kill 4752 

В то же время, называя пс показывает это:

4752 pts/4 00:00:00 simple <defunct> 

ответ

0

Вы убиваете себя. fork() возвращает 0, если вы находитесь в разветвленном процессе, или идентификатор дочернего процесса (PID) в процессе «master».

Итак, верхняя ветвь вашего предложения if() выполняется в основном процессе, где вы копируете идентификатор процесса ребенка (хранящийся в a) до child_pid.

В нижней ветви вы находитесь в процессе, в котором взять child_pid, который самостоятельно и затем счастливо убить() себя ... Вот почему вы никогда не получите строку «Killed с ...»

Как отметил paxdiablo, поскольку это дочерний процесс, он останется зомбиком до тех пор, пока вы не получите статус выхода с wait() или главный процесс не завершится.

Кстати, я не уверен, что вы хотите сделать с этим кодом:

  • Если вы хотите, чтобы выйти из дочернего процесса грациозно вы можете просто сделать выход().
  • Если вы хотите убить ваш дочерний процесс, отслеживайте дочерний PID (возвращаемый fork()), а затем kill() его из вашего основного процесса.
  • Если вы хотите убить мастер-процесс от вашего ребенка (как это ни странно), будьте осторожны, так как это может привести к его дочерним процессам. Вы должны отделить дочерний процесс от основного процесса (см. Страницу руководства для daemon()).
0

Ребенок процесс является мертвым, это просто, чтобы запись процесса зависала, пока кто-то не собирает код выхода.

Если родитель не делает этого, он в конечном итоге будет унаследован init, который пожнет его в какой-то момент.

+0

Но как Ctrl-C принудительно завершает процесс? – bob

+0

@bob Ctrl-C обрабатывается вашей оболочкой, которая отслеживает идентификаторы процессов своих дочерних элементов. Если вы нажмете Ctrl-C, оболочка выполнит kill (SIGTERM) в процессе (ваши «простые»), «простые» выходы, оболочка получит уведомление по сигналу, после чего оболочка собирает статус выхода с waitpid(). Это довольно сложный процесс ... Ключевым элементом здесь является wait()/waitpid(). – JvO

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