2011-03-01 4 views
4

간단한 코드 처리기를 코드에 넣었습니다. 신호를 잡는 핸들러 함수를 사용하여 구조체를 초기화했습니다.UNIX/Linux 신호 처리 : SIGEV_THREAD

코드가 작동하지 않는 이유를 지적 할 수 있습니까? 이론적으로 신호가 있으면 처리기를 호출해야합니다. 그러나 그렇지 않습니다.

이 제발 도와주세요, 감사 Kingsmasher1이

enter code here 
#include <stdlib.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <signal.h> 
#include <time.h> 

void my_handler(int sival_int, void* sival_ptr) 
{ 
printf("my_handler caught\n"); 
signal(sig,my_handler); 
} 

int main() 
{ 
struct sigevent sevp; 

sevp.sigev_notify=SIGEV_THREAD; 
sevp.sigev_signo=SIGRTMIN; 
sevp.sigev_value.sival_ptr=NULL; 
sevp.sigev_notify_function=(void*)my_handler; 
kill(0,SIGRTMIN); // This should invoke the signal and call the function 
} 

답변

13

struct sigevent은 프로세스가 신호를 처리하는 방법을 지정하지 않습니다. struct sigactionsigaction()은 어떻게 처리할까요? 대신 struct sigevent은 비동기 IO 완료 또는 타이머 만료와 같은 일부 비동기 이벤트를 프로세스에 알리는 방법을 지정하는 데 사용됩니다.

sigev_notify 필드는 이벤트 통지 방법을 지정 :

  • SIGEV_NONE - 전혀 통지를. 나머지 필드는 무시됩니다.
  • SIGEV_SIGNAL - 신호가 프로세스로 전송됩니다. sigev_signo 필드는 신호를 지정하고 sigev_value 필드는 신호 처리 함수에 전달되는 보충 데이터를 포함하며 나머지 필드는 무시됩니다.
  • SIGEV_THREAD - 함수가 새 스레드에서 호출됩니다. sigev_notify_function 필드는 호출 된 함수를 지정하고 sigev_value에는 함수에 전달되는 보충 데이터가 들어 있고 sigev_notify_attributes은 스레드 생성에 사용할 스레드 특성을 지정합니다. 나머지 필드는 무시됩니다. 당신이 SIGEV_THREAD을 설정하면 sigev_signo 필드가 무시됩니다 특히

주 - struct sigevent하지 신호가 그 방법으로 스레드 지정에 대한 스레드 또는 통지 방법으로 신호 중 하나 지정에 관한 것입니다 처리해야합니다.

struct sigevent도 알림을 보낼 비동기 이벤트를 설정하는 timer_create()과 같은 함수에 전달되어야합니다. struct sigevent 개체를 만드는 것만으로는 특별한 작업을 수행 할 수 없습니다.

전용 스레드를 사용하여 신호를 처리하려면 스레드 앞쪽에 스레드를 만들고 루프를 걸어서 sigwaitinfo()을 차단하십시오. sigprocmask()을 사용하여 다른 모든 스레드에서 신호를 차단하십시오.

2

나는 당신이 여기 신호 처리 숙어를 혼합 생각, 당신은 sigevent 구조를 만들고 그것으로 아무것도하지 않고 다음 신호에서 신호()를 사용 매니저. 다음 코드는 코드를 기반으로하는 매우 간단한 신호 처리 루틴을 보여줍니다. my_handler의 정의를 변경했습니다. 좀더 정교한 처리가 필요하다면 sigaction() 함수를 호출해야한다.

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

void my_handler(int sig) 
{ 
printf("my_handler caught\n"); 
signal(sig,my_handler); 
} 

int main() 
{ 
signal(SIGRTMIN,my_handler); 
kill(0,SIGRTMIN); // This should invoke the signal and call the function 
while(1) ; // Infinite loop in case the program ends before the signal gets caught! 
} 

int main() 
{ 
signal(SIGRTMIN,my_handler); 
kill(0,SIGRTMIN); // This should invoke the signal and call the function 
while(1) ; // Infinite loop in case the program ends before the signal gets caught! 
} 

이것은 내 Windows 상자의 cygwin에서 작동합니다 (분당 리눅스 상자에 액세스 할 수 없음).

+0

하지만 OP는 'sigevent' **로 논리적으로 문제가되지 않아야합니다. 따라서 +1해야합니다. –

+0

이 메소 나는 알고 있지만, 나는 sigevent를 사용하고 SIGEV_THREAD를 사용하여 함수를 호출하려고합니다. 만약 당신이 저를 도울 수 있다면, 그것은 위대 할 것입니다. – kingsmasher1

+0

문서를 통한 짧은 트롤에서 당신이 가진 문제는 시그널 핸들링이 아니라 시그널 핸들링에 관한 것입니다. sigevent가 async io (aio man 페이지 참조)와 같은 용도로 사용되는 동안 SIGRTMIN 신호가 프로세스에서 수신 될 때마다 새 스레드에서 신호 처리기를 호출하려는 것처럼 들립니다. 당신은 signal()에 대한 문서를보고 당신이 할 수있는 것을보기 위해 당신의 OS가 그것을 지원한다면 sigaction()을 필요로한다. – Jackson

0

희망하시는 바입니다.

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

void 
my_handler (int sig) 
{ 
    printf ("my_handler caught\n"); 
    signal (sig, my_handler); 
} 

int 
main() 
{ 
    int signo; 
    struct sigevent sevp; 
    sigset_t set; 

    if (sigemptyset (&set) == -1) 
     perror ("sigemptyset"); 
    if (sigaddset (&set, SIGRTMIN) == -1) 
     perror ("sigaddset"); 
    if (sigprocmask (SIG_BLOCK, &set, NULL) == -1) 
     perror ("sigprocmask"); 

    sevp.sigev_notify = SIGEV_THREAD; 
    sevp.sigev_signo = SIGRTMIN; 
    sevp.sigev_value.sival_ptr = NULL; 
    kill (0, SIGRTMIN); 
    if (sigwait (&set, &signo) == 0) 
     my_handler (signo); 
    else 
     perror ("sigwait"); 
}