2012-02-10 5 views
2

프로세스가 있으며 프로세스가 종료되면 다시 시작하려고합니다. 이것을 달성하기 위해 나는 부모의 살해를 잡기 위해 prctl(PR_SET_PDEATHSIG, SIGHUP);을 사용하는 자식 "보호자"과정을 시작하고 다시 시작합니다.SIGHUP으로 죽인 프로세스를 다시 시작하십시오.

int main() { 
    if (fork() == 0) { 
     execl("./guardian", 0); 
    } 
    while (1) { 
     cout << "I am process\n"; 
     sleep(1); 
    } 
    return 0; 
} 

내가 가진 문제는 단지 한 번 작동한다는 것입니다 :

void restart (int signal) { 
    if (getppid() == 1) { 
     if (fork() == 0) { 
      execl("./process", 0); 
     } 
     exit(1); 
    } 
} 

int main() { 
    prctl(PR_SET_PDEATHSIG, SIGHUP, NULL, NULL, NULL); 

    struct sigaction new_action, old_action; 
    new_action.sa_handler = restart; 
    sigemptyset (&new_action.sa_mask); 
    new_action.sa_flags = 0; 

    sigaction (SIGHUP, NULL, &old_action); 

    if (old_action.sa_handler != SIG_IGN) { 
     sigaction (SIGHUP, &new_action, NULL); 
    } 

    while (getppid() != 1) { 
     sleep(86400000); 
    } 
    return 0; 
} 

그리고 부모 : 여기

는 (생략 로깅) 보호자의 코드입니다. 처음으로 프로세스가 시작될 때 ps 출력은 다음과 같습니다.

USER  PID %CPU %MEM VSZ RSS TTY  STAT START TIME COMMAND 
1012  13058 0.0 0.3 20244 1932 pts/1 Ss 08:22 0:00 -sh 
1012  22084 0.0 0.1 11484 1004 pts/1 S+ 11:20 0:00 \_ ./process 
1012  22085 0.0 0.1 11484 1000 pts/1 S+ 11:20 0:00  \_ [guardian] 
1012  12510 0.0 0.3 20784 1712 pts/0 Ss 08:14 0:00 -sh 
1012  22088 0.0 0.1 17412 1012 pts/0 R+ 11:20 0:00 \_ ps fu 

다음으로 kill -9 22084으로 프로세스를 종료합니다. 그리고 다시 ps 출력 : 다시 프로세스를 종료 할 때

USER  PID %CPU %MEM VSZ RSS TTY  STAT START TIME COMMAND 
1012  13058 0.0 0.3 20244 1932 pts/1 Ss+ 08:22 0:00 -sh 
1012  12510 0.0 0.3 20784 1712 pts/0 Ss 08:14 0:00 -sh 
1012  22091 0.0 0.1 17412 1012 pts/0 R+ 11:21 0:00 \_ ps fu 
1012  22089 0.0 0.1 11484 996 pts/1 S 11:20 0:00 [process] 
1012  22090 0.0 0.1 11484 996 pts/1 S 11:20 0:00 \_ [guardian] 

kill -9 22089 보호자 (그들은 여기 생략 내가 로그에서 확인) SIGHUP 콜백을 얻을하지 않는 것 같습니다.

USER  PID %CPU %MEM VSZ RSS TTY  STAT START TIME COMMAND 
1012  13058 0.0 0.3 20244 1932 pts/1 Ss+ 08:22 0:00 -sh 
1012  12510 0.0 0.3 20784 1712 pts/0 Rs 08:14 0:00 -sh 
1012  22339 0.0 0.1 17412 1008 pts/0 R+ 11:27 0:00 \_ ps fu 
1012  22090 0.0 0.1 11484 996 pts/1 S 11:20 0:00 [guardian] 

내 질문은 - 보호자가 SIGHUP을받지 못하는 이유는 무엇입니까?

백그라운드 프로세스 그룹과 관련이있는 것으로 의심됩니다. 프로세스를 다시 시작하면 백그라운드 그룹에 있습니다 (ps stat의 S + 및 S 비교).

+0

이것은 미친 짓입니다. 아이가 부모를 다시 시작하게하는 대신에, 부모가 아이를 다시 시작하게하지 않는 이유는 무엇입니까? 전체 시스템은 그렇게하는 것이 쉽다. –

+0

네,이게 너무 많은 의미가 없다는 것을 압니다. 내 안드로이드 응용 프로그램에서 가지고있는 프로세스 재시작 논리를 재현하고 있습니다. 안드로이드는 앱 (부모 프로세스)을 시작하고 프로세스는 부모의 상태를 모니터링하는 보호자 (자식 프로세스)를 시작합니다. – lstipakov

+0

@WilliamPursell : 그렇게 미친 짓. 내 바이러스 백신 소프트웨어는 분명히 비슷한 것을합니다. 바이러스 백신 프로그램을 종료하는 것은 표준 해커 전략이기 때문에 바이러스 백신 프로그램은 자체의 여러 인스턴스를 만들고 이들 각각은 사망 한 부모를 감시하는 보호자를 만듭니다. Kill -9는 차단이 불가능하고 감지 할 수 없습니다. 응용 프로그램이 죽을 수도 있습니다. 그것은 자식 프로세스에서 탐지 가능합니다. –

답변

4

SIGHUP 신호 처리기를 사용하는 동안 SIGHUP이 차단 된 것으로 보입니다. fork()exec()은 신호 마스크를 상속하므로 두 번째 보호자는 신호 마스크를 다시받지 못합니다.

차단 해제 SIGHUP 신호 처리기에서 fork() 다음에 exec() 부모보다 앞에있는 동안.

+2

sigset_t x; sigemptyset (&x); sigaddset (& x, SIGHUP); sigprocmask (SIG_UNBLOCK, & x, NULL); – lstipakov

+0

깔끔한 원 라이너!) –

관련 문제