2014-10-04 2 views
1

주 메소드 내에서 두 구조를 초기화하는 간단한 프로그램이 있습니다. 사용자가 ctrl-c를 눌러 할당 한 두 구조체를 해제 할 때 신호 이벤트 처리기를 추가하려고합니다.C에서 콜백없이 SIGINT 신호 사용

이 두 구조체를 전역 변수로 만들고 싶지 않습니다. 인라인 콜백을 사용하여 신호 함수를 호출하는 방법이 있습니까? 이 같은

뭔가 :

int main(int argc, char **argv) 
{ 
    //initialize structs 

    signal(SIGINT, { 
     //free structs on ctrl-c 
    }); 
} 

어떤 조언을 주시면 감사하겠습니다, 감사합니다.

+1

는 제 커널은 핸들러로 호출 할 수있는 함수의 주소를 필요로한다. –

답변

1

다른 사람이 말했듯이, 당신은 당신이 요구하는지 정확하게 할 수 없습니다.

같은 목적을 달성하는 동안 이러한 변수를 전역으로 만드는 것을 피하는 다른 방법은 물론 있습니다. 가치있는 일인지 여부는 상황에 따라 다릅니다. 여기에 free()에 원하는 물건을 유틸리티 함수로 등록하고 신호 처리기에서 호출하는 방법이 있습니다.

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

#define STACK_SIZE 100 

struct mystruct { 
    int a; 
    int b; 
}; 

enum manage_action { 
    MYSTRUCT_STORE, 
    MYSTRUCT_FREE 
}; 

void manage_allocs(void * p, enum manage_action act) 
{ 
    static void * ptr_stack[STACK_SIZE]; 
    static int top = 0; 

    switch (act) { 
     case MYSTRUCT_STORE: 
      if (top == STACK_SIZE) { 
       perror("Stack overflow"); 
       exit(EXIT_FAILURE); 
      } 
      ptr_stack[top++] = p; 
      break; 

     case MYSTRUCT_FREE: 
      for (int i = 0; i < top; ++i) { 
       free(ptr_stack[i]); 
      } 
      top = 0; 
      break; 
    } 
} 

void handler(int dummy) 
{ 
    manage_allocs(NULL, MYSTRUCT_FREE); 
} 

int main(void) { 
    struct mystruct * a = malloc(sizeof *a); 
    struct mystruct * b = malloc(sizeof *b); 
    if (!a || !b) { 
     perror("Couldn't allocate memory"); 
     return EXIT_FAILURE; 
    } 

    manage_allocs(a, MYSTRUCT_STORE); 
    manage_allocs(b, MYSTRUCT_STORE); 

    signal(SIGINT, handler); 
    pause(); 

    return 0; 
} 

free()는-비동기 안전이 보장되지 (어느 쪽도 전체의 manage_allocs() 기능은 그 문제이다), 그래서 시그널 핸들러에서 호출에 대한 일반적인주의 사항이 적용 것, 그리고 확실하고 있습니다되지 않는다 그것은 결코 다시 입력되지 않을 것입니다.

1

커널에는 신호가 수신 될 때 호출 할 수있는 함수에 대한 포인터가 있어야합니다. 따라서 인라인 함수가 될 수 없습니다.

은 따라서 귀하의 질문에 간결하게 대답은 없습니다 :

없음

0

"간단한"프로그램 이 단일 스레드 단일 .c 소스 파일로 구성되어있는 경우 전역 변수를 사용하지 않는 방법에 동의하지 않습니다.

그러나 범위가 단일 소스로 제한되는 전역 변수를 허용하려는 경우 여러 .c 소스를 사용할 수 있습니다 (예 : main.c & sig.c) ... 즉 신호 처리기를 넣고, sig.c의 시그널 설치자 함수 ... 시그널 핸들러에 의해 free'd 될 주소로 'installer'가 호출 될 것입니다. 'installer'는 주소를 정적 전역 변수로 저장합니다 ... 전역 범위를 sig.c로 제한하면서 신호 처리기에서 사용할 수있게 만듭니다. 이 여전히 전역 변수입니다 ...하지만 "로컬 전역 변수"입니다 수여

... 간결