2016-10-24 1 views
1

자식 (r.out)을 시작하는 프로그램이 있으며 그 자식에는 시간 제한이 있습니다.제한 시간 후에 완료되지 않은 경우 자식 프로세스를 중지하는 방법

제한 시간이 지난 후 r.out 실행을 중지하는 방법을 알고 싶습니다.

나는 리눅스에서 코드를 실행 중이다. 아이를 죽일하기 위해

#include <unistd.h> 
#include <signal.h> 
#include <err.h> 
#include <stdio.h> 
#include <stdlib.h> 

#define TIME_LIMIT 1    //determine time limit 

void my_function();   //supposed to include the submitted code 
void alarm_handler(int); 



int main() 
{ 
    if (sigaction(SIGALRM, NULL, NULL) == -1) 
     err(1, NULL); 

    signal(SIGALRM, alarm_handler); // assigning an alarm handler for SIGALRM 

    alarm(TIME_LIMIT); // install an alarm to be fired after TIME_LIMIT 

    system("./r.out"); //Running the file 

    alarm(0); 
    return 0; 
} 


void alarm_handler(int sig) 
{ 
    printf("%s" , "Time limit exceeded"); 
    //Here i want a code to stop the r.out file 
} 
+0

코드 검토 서비스가 없습니다. – Olaf

+0

스레딩을 사용할 수 있습니까? 그렇다면'r.out'을 쓰레드에서 실행시키고'n' 초 후에 쓰레드를 죽일 수 있습니다. –

+1

'SIGKILL'을 보내십시오. 그러나 더 잘 제어하려면'fork/exec' 명령으로 더 잘 스폰하십시오. –

답변

0

, 당신은 PID를 알아야합니다

이것은 내가 지금까지있는 것입니다. system 대신 forkexec으로 프로그램을 시작하면 얻을 수 있습니다.

SIGALRM의 신호 처리기 외에도 SIGCHLD (하위 프로세스가 완료되면 수신 됨)에 대해 하나를 설정하십시오. alarm을 호출하여 타이머를 설정 한 후 pause으로 전화하십시오. 이 기능은 두 신호 중 하나를 가져올 때 돌아옵니다.

신호 처리기에서 전역 플래그 만 설정해야합니다. 신호 처리기 내에서 printf을 호출하면 정의되지 않은 동작이 발생할 수 있습니다.

pause이 반환 된 후 두 플래그를 각각 확인하십시오. 시간 초과 플래그가 설정되면 kill으로 자식을 종료 할 수 있습니다.

두 경우 모두 wait으로 전화하여 하위 프로세스의 PID를 얻으십시오.

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

#define TIME_LIMIT 1    //determine time limit 

void alarm_handler(int); 
void child_handler(int); 

int timeout = 0; 
int child_done = 0; 

int main() 
{ 
    pid_t pid = fork(); 
    if (pid == -1) { 
     perror("fork failed"); 
     exit(1); 
    } else if (pid == 0) { 
     // child process 
     execl("./r.out","r.out", NULL); 
     perror("exec failed"); 
     _exit(1); 
    } 

    // set up the signal handlers after forking so the child doesn't inherit them 

    signal(SIGALRM, alarm_handler); 
    signal(SIGCHLD, child_handler); 

    alarm(TIME_LIMIT); // install an alarm to be fired after TIME_LIMIT 
    pause(); 

    if (timeout) { 
     printf("alarm triggered\n"); 
     int result = waitpid(pid, NULL, WNOHANG); 
     if (result == 0) { 
      // child still running, so kill it 
      printf("killing child\n"); 
      kill(pid, 9); 
      wait(NULL); 
     } else { 
      printf("alarm triggered, but child finished normally\n"); 
     } 
    } else if (child_done) { 
     printf("child finished normally\n"); 
     wait(NULL); 
    } 

    return 0; 
} 


void child_handler(int sig) 
{ 
    child_done = 1; 
} 

void alarm_handler(int sig) 
{ 
    timeout = 1; 
} 
+0

나는 과용이라고 생각합니다. 더미'SIGALRM' 핸들러를 설치하고'wait'를 실행하고'EINTR'로'-1'을 리턴하면'kill'을 수행하십시오. timeout,'pause' 및'SIGCHLD'를 처리 할 필요가 없습니다. – user58697

+0

@ user58697 내가 테스트를하고있는 컴퓨터에서, 타이머가 만료되었을 때'wait'는'EINTR'과 함께 -1을 반환하지 않을 것입니다. 이 방법은 모든 것이 만료 된 경우와 완료된 경우 모두에서 작동하는지 확인하는 데 필요했습니다. – dbush

+0

이것은 매우 이상합니다. 'wait' 행동은 완벽하게 정의되어있다. 그 기계는 무엇 이었을까? – user58697

관련 문제