2017-04-05 15 views
0

3 번 자식 프로세스에 신호를 보내야합니다.좀비 상태를 피하면서 자녀에게 여러 번 신호를 보내려면 어떻게해야합니까? C 언어

문제는 어린이가 신호를 한 번받은 다음 좀비로 변하는 것입니다. 나는 아이 11385 해요

을 그리고 난 내가 아이 11385 해요

SIGUSR1

받은 나는 아이 11,385 그리고 난

SIGUSR1

받은 :

예상 출력 될 것이다 SIGUSR1

받은하지만 실제 출력은 다음과 같습니다 나는 아이 11385 해요

와 나는 SIGUSR1

01받은
#include <ctype.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <signal.h> 
#include <sys/types.h> 
#include <sys/wait.h> 

void my_handler() 
{ 
    printf("\n I'm the child %i and i received SIGUSR1\n", getpid()); 
} 


int main (int argc, char **argv) { 
    int *array; 
    int N = 10; 
    int i; 
    pid_t pid1; 
    array=(int*)malloc(sizeof(int)*N); 


    signal(SIGUSR1,my_handler); 

    for (i = 0; i< N; i++) 
    { 
     pid1 = fork(); 
     if(pid1 < 0) 
     { 
      exit(EXIT_FAILURE); 
     } 
     else if (pid1 > 0) 
     { 
      array[i]= pid1; 
     } 

     else 
     { 
      sleep(100); 
      exit(EXIT_SUCCESS); 
     } 
    } 

    i=0; 
    while(i<3) // I need to call the son 3 times 
    { 
     kill(array[1], SIGUSR1); 
     i++; 
    } 
} 
+0

'무효 my_handler()'- >>'무효 my_handler (INT의 부호 요소가)'도 그리고 [잘못된 서명으로, 신호 처리기의 반환을 효과적으로 자녀를 죽이는] : 당신 시그널 핸들러 내부에서 printf()를 호출해서는 안된다. – wildplasser

+0

@wildplasser 코드는 특정 신호에 대한 예제이므로 인수가 없습니다. printf도 예제이며 실제 문제는 아닙니다 :/ –

+0

하지만 스택을 방해하는 ** 인수 **가 있습니다 (반환시) – wildplasser

답변

1

어린이가 신호를 받으면 sleep이 종료 될 때까지 기다리는 중일 수 있습니다. 첫 번째 신호는 시간이 만료되지 않은 경우에도 sleep을 인터럽트하므로 errnoEINTR으로 설정된 경우 반환됩니다. 자고 싶다면 sleep으로 다시 전화해야합니다.

+0

잠을 더하고 메시지를 두 번 표시합니다. 4를 추가하면 4 번 표시됩니다. N은 어떻게 잠합니까? 어쨌든, 잠자기로 인해 프로세스가 종료되지 않습니다. SIGTERM 신호가 작동하지 않음 –

+0

sleep을 루프에 넣기 SIGTERM 핸들러는 루프가 종료되어야 함을 나타내는 전역 변수를 설정해야합니다 (변수는 volatile이어야 함) – rici

+0

또는 sleep의 반환 값을 확인하십시오. 이유가 있습니다. 사실,이 유스 케이스에는 꽤 많이 있습니다. –

1
  • 상위 프로세스
  • 신호가 고속으로 전송 될 수있는 아이 보내고 대기()없이 종료, I 내가 신호를 더 지연을
  • 올바른 서명을 추가
  • 짧은 지연을 추가 handler는 void handler(int signum)입니다. 핸들러가 인수와 함께 호출되고 스택 핸들러가 신호 핸들러와 다르기 때문에 이는 매우 중요합니다.
  • 신호 처리기에서 printf()를 호출하면 안되며 비동기 안전하지 않습니다.

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

char pidstr[10]; 
char massage[]="  I'm the child and i received SIGUSR1\n"; 

#define CNT 1 
void my_handler(int signum) 
{ 
write(0, massage, strlen(massage)); 
} 


int main (int argc, char **argv) { 
    int i , err, status; 
    pid_t pid1; 
    int array[CNT]; 

    signal(SIGUSR1, my_handler); 

    for (i = 0; i< CNT; i++) { 
     pid1 = fork(); 
     if(pid1 < 0) { exit(EXIT_FAILURE); } 
     else if (pid1 > 0) { 
       printf("ChildPid=%d\n", pid1); 
      array[i]= pid1; 
     } 

     else 
     { // child 
       // signal(SIGUSR1, my_handler); 
      sprintf(pidstr,"[%d]", getpid()); 
      memcpy (massage,pidstr, strlen(pidstr)); 
      sleep(10); 
       printf("Unslept\n"); 
      sleep(10); 
       printf("Unslept\n"); 
      sleep(10); 
       printf("Unslept\n"); 
      exit(EXIT_SUCCESS); 
     } 
    } 
    sleep(10); 
    for (i=0; i<3; i++) { 
     err = kill(array[0], SIGUSR1); 
     printf("Err=%d:%d\n", err, (err) ? errno: 0); 
     sleep(1); 
    } 

    while ((pid1=wait(&status)) != -1){ 
     printf("[Parent] Reaped %d\n", pid1); 
     } 

return 0; 
}