독학 Linux-sigaction function

6746 단어
#include<signal.h>
int sigaction(int sig, struct sigaction *act , struct sigaction *oact) ;

struct sigaction{
      void     (*sa_handler)(int);
      void     (*sa_sigaction)(int, siginfo_t *, void *);
      sigset_t   sa_mask;
      int        sa_flags;
      void     (*sa_restorer)(void);
}

이 함수는 괜찮다
:
1.signal에 handler를 설치하고sigaction을 사용하여 이 handler를 수정하기 전에 Reinstall을 사용하지 않습니다
2.sigaction 구조를 사용합니다. 이 구조는handler를 포함하고 그 중에서 2개의 handler를 지정할 수 있습니다. 하나는sigiinfo_를 사용합니다.t 등 매개 변수의handler, 즉handler에 더 많은 매개 변수를 지원하여 자신이 어떤 프로세스, 그 사용자, 어떤 신호를 보냈는지, 이 신호를 보낸 구체적인 원인이 무엇인지 알 수 있도록 한다. 물론,sigaction의sa_flags 설정 SA_SIGINFO 태그.
3.sigaction을 사용한 사_flags 표시는 시스템 호출이 이 신호에 끊긴 후에 바로 되돌아올지, 자동restart로 돌아올지 지정할 수 있습니다.전형적인 것은 일반적으로 우리가 SIGALRM 신호가 끊어지는 시스템에서 restart를 호출하지 못하게 하는 것이다. 왜냐하면 SIGALARM은 일반적으로 블록의 호출을 끊는 데 사용되기 때문이다.
4. 오래된 시그널 함수의 작용을 모방하여 unreliable의 유사한 시그널 조작을 실현하기 위해sa_flags 설정 SA_RESETHAND를 사용하면 handler가 자동으로 재설치되지 않고 SA_NODEFER 표시는 이 신호의handler 내부에서 이 신호가 자동block되지 않도록 합니다. 물론 당신이 수동으로sa_마스크에서 이 신호를 블록할 것을 지정하면 블록을 할 수 있습니다.
5.sigaction 구조의 사_를 사용하여mask, 이handler가 실행하는 과정에서 block의 일부 신호는 주의할 수 있습니다. 이mask는 우리가sigprocmask에서 설정한mask와 다른mask입니다. 이mask의 작용 범위는 본 handler 함수에 한정되며, 우리가sigprocmask로 설정한mask를 취소하지 않고 그 기초 위에서 다시 일부 신호block을 제거합니다. handler가 끝날 때 시스템은 자동으로mask를 이전의 모습으로 회복합니다.그래서 이sigaction의 사_mask는 본 신호의handler의 실행 시간만 작용합니다.
이 밖에 시스템은 하나의signalhandler가 실행될 때 다시 이 signal에 의해 끊어지는 것을 피하기 위해 자동으로 이 handler가 실행되기 전에 이 signal을sigaction의sa_에 추가합니다mask에서 본handler의 실행 과정에서 본signal의 끼워 넣는 방해를 받지 않습니다. 만약에 본handler가 대응하는 신호가 실제로 발생한다면 이 신호는 본handler가 실행한 후에 실행되지만 한 번만 실행됩니다. 왜냐하면 한 번만 기록할 수 있기 때문입니다. 물론 이번 새로운 실행에서 또 이런 상황이 발생하면 되돌아가야 합니다.다음은 코드입니다. 코드는 다음과 같은 몇 가지를 검증했습니다.
(1).Sigaction은 handler가 이 signal을 임시 block에 자동으로
(2). 한handler가 실행하는 과정에서 임시 블록에 떨어진 신호도 기록되고,handler가 완성되면delivery됩니다.
다음 예에서,
child
처음부터
pause()
신호가 오기를 기다리고,
father
그에게 보내다
SIGUSR1
신호
father
들어가다

초간의 수면, 이것은 기다리기 위한 것이다
child
그의
handler
안으로 들어가 잠을 자다.
Child
받다
SIGUSR1
후.지금 실행
handler
하면, 만약, 만약...

초간의 수면.그렇게 보면
father
자다

초 후,
child
아직도 자고 있고
handler
안에서 자다.지금
father
연속 발송 가능

차례
SIGUSR1
주다
child
발견하다
child
호응하지 않고 그녀의 남은 시간을 충분히 잤다.

초 동안 수면이 끝난 후,
child
깨어나다
handler
종료, 시스템이 자동으로 임시
block

SIGUSR1 unblock
, 지금 발견
pending

SIGUSR1
그래서 그를
delivery
주다
child
.그래서
child
재진입
handler
지금
father
이미 더 이상 신호를 보내지 않고 아이가 끝나기를 기다리고 있다.그래서
handler
끝나면,
child
계속 실행, 종료, 그리고
father
그냥 물러났어요.
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>

void nullhandler( int num )
{
       puts( "child received  signal" );
       puts( "child sleep 5 secs in handler..." );
       sleep(5);
       puts( "child wake up in handler after 5 secs" );
}

int main()
{
       setbuf( stdout, NULL );
       int pid = fork();
       if( pid == 0 )
       {
              //child
              puts("child started");
	      printf("%d",getpid());
/*          
              sigset_t maskset,oldset,oldset1;
              sigemptyset( &maskset );
              sigaddset( &maskset, SIGUSR1 );
              sigprocmask( SIG_BLOCK, &maskset, &oldset );
*/
              struct sigaction act, oldact;
              act.sa_handler = nullhandler;
              sigemptyset( &act.sa_mask );
              if( sigaction( SIGUSR1, &act,0 ) < 0 )
              {
                     puts(" child install handler failed");
                     return -1;
              }
              /*
              puts("child went to sleep ...");
              sleep(5);
              puts("child wake up...");
              sigset_t pendset;
              if( sigpending( &pendset ) < 0  )
              {
                     puts("get pending signal failed");
                     return -1;
              }
              if( sigismember( &pendset, SIGUSR1 ) )
                     puts("SIGUSR1 is pending signal");
              else
                     puts("SIGUSR1 is pending signal");
              puts("child is unblocking signal");
              if( sigprocmask(SIG_UNBLOCK, &maskset, &oldset1 ) < 0 )
                     puts("unblock signal failed");
              else
                     puts("unblock signal success");
              */
              puts("child waiting for signal...");
              /*pause , terminal , , 。*/
              pause();
              puts("child returnd from signal handler");
              puts("child  is quiting");
              exit(0);
       }
       sleep(1);
       puts( " father send  SIGUSR1 once" );
       int ret = kill( pid, SIGUSR1 );
       puts("father sleep 1 sec to ensure child is now in signal handler");
       sleep(1);
       puts( " father send  SIGUSR1 twice" );
       ret = kill( pid, SIGUSR1 );
       puts( " father send  SIGUSR1 third times" );
       ret = kill( pid, SIGUSR1 );
       /* 。*/
       waitpid( pid, 0, 0);
       puts("father is quiting");
       return 0;
}

출력 결과:
child started
child waiting for signal...
father send  SIGUSR1 once
father sleep 1 sec to ensure child is now in signal handler
child received  signal
child sleep 5 secs in handler...
father send  SIGUSR1 twice
father send  SIGUSR1 third times
child wake up in handler after 5 secs
child received  signal
child sleep 5 secs in handler...
child wake up in handler after 5 secs
child returnd from signal handler
child  is quiting
         father is quiting
큰 소의 문장에 대한 지도에 감사 드립니다.http://blog.chinaunix.net/space.php?uid=12072359&do=blog&id=2961076

좋은 웹페이지 즐겨찾기