Linux C 프로 그래 밍 신호 소개

5700 단어
며칠 간 C 언어 로 간단 한 SHELL 을 구현 하 는 CSAPP 실험 을 쓰 고, 이 실험 을 하기 위해 APUE 신호 와 관련 된 내용 을 한 번 보고, 여기 서 여러분 과 공유 하 겠 습 니 다.
유 닉 스 신호 사용 요약:
신호 의 원리:
신 호 는 프로 세 스 통신 의 방법 으로 그 는 비동기 사건 의 처리 에 응용 된다.신호 의 실현 은 일종 의 소프트 인 터 럽 트 이다.실행 중인 프로 세 스 로 보 내 졌 습 니 다. 어떤 이벤트 가 발생 했 는 지 알려 주 었 습 니 다.
1.1 신호 생 성:
신호 처리 로 운영 체제 의 중단 기능 을 모 의 하 다.신호 처리 기능 을 사용 하려 면 신호 처리 함 수 를 작성 하면 된다.
(1) 시그 널 함수 호출
함수 원형 은 다음 과 같 습 니 다: void signal (int signo, void * handler);signo 는 신호 형식 이 고 뒤 에는 신호 처리 함수 입 니 다.
(2) kill 함수 호출
신 호 를 보 내 는 함 수 를 봉인 할 수 있 습 니 다:
int send_signal(pid_t pid, int sig) {
    if (kill(pid, sig) < 0) {
        /* fail silently if pid doesn't exist -- this keeps handlers that
         are called too close together from complaining */
        if (errno != ESRCH)
            unix_error("send_signal: kill failed");
    }
    return 0;
}

kill 함 수 를 통 해 pid 프로 세 스에 신 호 를 보 냅 니 다.
(3) sigaction 함수 로 시그 널 을 밀봉 합 니 다.
sigaction 의 구 조 는 다음 과 같다.
struct sigaction

{

     void(*sa_handler)(int);

     void(*sa_sigaction)(int,siginfo_t *,void *);

     sigset_tsa_mask;

     intsa_flags;

}

sigaction 의 매개 변수 값 을 설정 하여 sinal 에 대한 패 키 징 을 얻 을 수 있 습 니 다.
1.2 신호 집합 조작
(1) 신호 집합의 개념
실제 응용 에서 한 응용 프로그램 은 여러 개의 신 호 를 처리 해 야 하기 때문에 편리 하도록 Liux 시스템 은 신호 집합 이라는 개념 을 도입 했다.신호 집합 은 여러 신호 로 구 성 된 데이터 형식 sigsett. 다음 시스템 호출 설정 신호 에 포 함 된 데 이 터 를 사용 할 수 있 습 니 다.시스템 에서 이렇게 정의 합 니 다.
typedef struct { unsignedlong sig[_NSIG_WORDS];} sigset_t;
(2) 신호 집합의 조작
신호 집합 작업
다음 과 같은 몇 가지 가 있다.
int sigemptyset(sigset_t *set);

int sigfillset(sigset_t *set);

int sigadd(sigset_t *set,int setnumber);

int sigdelset(sigset_t *set,int setnumber);

int sigismember(sigset_t *set,int setnumber);

사용 방법:
보통 sigemptyset 함 수 를 사용 하여 신호 집합 을 초기 화 한 다음 sigadd 를 호출 하여 처리 해 야 할 신 호 를 추가 해 야 신 호 를 차단 할 수 있 습 니 다.
(3) 신호 차단
때때로 신 호 를 받 았 을 때 즉시 현재 실행 을 멈 추고 신 호 를 처리 하 는 것 을 원 하지 않 으 며, 동시에 이 신 호 를 무시 하고 신호 처리 함 수 를 호출 하 는 것 을 원 하지 않 는 다.이런 상황 은 차단 신 호 를 통 해 이 루어 진 것 이다.가로막았어
개념 과 무시 신 호 는 다르다.운영 체 제 는 신호 가 프로 세 스 에 의 해 차단 되 기 전에 신 호 를 전달 하지 않 고 차단 되 는 신호 도 프로 세 스 의 행위 에 영향 을 주지 않 으 며 신 호 는 일시 적 으로 전달 을 막 을 뿐이다.프로 세 스 가 신 호 를 무시 할 때
신 호 는 전달 되 지만 프로 세 스 는 신 호 를 버 립 니 다.신호 가 막 혔 을 때 만약 에 이런 신호 가 여러 번 발생 하면 차단 이 완 료 된 후에 이런 신호 만 호출 하고 차단 과정 에서 이런 신 호 는?
미결이었어
신호 차단 처 리 는 다음 과 같은 몇 가지 함수 와 관련된다.
1. sigprocmask 함수
int sigprocmask(ubt how,const sigset_t*set,sigset_t *oldset);
sigprocmask 는 신호 차단 집합 내의 신호 에 대한 처리 방식 을 설정 합 니 다 (차단 하거나 차단 하지 않 음).
인자:
how: 신호 수정 방식 을 지정 합 니 다. 세 가지 선택 이 가능 합 니 다.
SIG_BLOCK//set 가 가리 키 는 신 호 를 현재 신호 마스크 에 집중 적 으로 추가 합 니 다.즉, 신호 마스크 와 set 신호 집합 을 진행 하거나 조작 하 는 것 이다.
SIG_UNBLOCK//set 가 가리 키 는 신 호 를 현재 신호 마스크 에서 삭제 합 니 다.즉, 신호 마스크 와 set 가 작 동 합 니 다.
SIG_SETMASK//set 의 값 을 새로운 프로 세 스 신호 마스크 로 설정 합 니 다.즉 set 는 신호 마스크 에 대해 할당 작업 을 했다.
set: 신호 집합 을 가리 키 는 지침 입 니 다. 이 는 신 설 된 신호 집합 을 말 합 니 다. 현재 차단 값 만 읽 으 려 면 NULL 로 설정 할 수 있 습 니 다.
oldset: 신호 집합 을 가리 키 는 지침 이기 도 합 니 다. 여기에 원래 의 신호 집합 을 저장 합 니 다.신호 마스크 에 어떤 신호 가 있 는 지 검사 하 는 데 사용 할 수 있다.
설명 을 되 돌려 줍 니 다:
성공 적 으로 실행 되 었 을 때 0 을 되 돌려 줍 니 다.실패 반환 - 1, errno 는 EINVAL 로 설정 되 었 습 니 다.
2. sigsuspend 함수
int sigsuspend(const sigset_t *sigmask);
이 함 수 는 프로 세 스 의 연결 에 사 용 됩 니 다. sigmask 는 신호 집합 을 가리 키 고 있 습 니 다.이 함수 가 호출 될 때 sigmask 가 가리 키 는 신호 집중 신 호 는 신호 마스크 에 값 을 부여 합 니 다.다음 프로 세 스 가 끊 깁 니 다.프로 세 스 가 신 호 를 포착 할 때 까지
처리 함 수 를 되 돌려 줄 때 함수 siguspend 를 되 돌려 줍 니 다.신호 마스크 를 신호 호출 전의 값 으로 복원 하고 errno 를 EINTR 로 설정 합 니 다.프로 세 스 종료 신 호 는 즉시 정지 할 수 있 습 니 다.
3. sigpending 함수
차 함 수 는 현재 신호 가 미결 상태 에 있 는 지 판단 하 는 것 이다.
1.3 wait () 와 waitpid ()
wait 와 waitpid 는 경직 된 프로 세 스 를 처리 하 는 함수 입 니 다. 일반적으로 while 순환 에서 이 두 함 수 를 사용 하여 경직 된 프로 세 스 를 처리 합 니 다.
실례:
앞에서 이렇게 많은 신호 에 관 한 것 을 소 개 했 습 니 다. 다음은 실례 를 보 겠 습 니 다.
#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"
#include "signal.h"

char *id = "terminal
"; int count = 0; static void do_termal(int sig) { ++count; //write(1,id,strlen(id)); printf("aaaaa
"); } static void do_stop(int sig) { ++count; //write(1,id,strlen(id)); printf("stop
"); } int main() { struct sigaction sa_oact; struct sigaction sa_nact; sigset_t pendmask; sa_nact.sa_handler = do_termal; sa_nact.sa_flags = 0; sigemptyset(&sa_nact.sa_mask); sigaddset(&sa_nact.sa_mask, SIGTSTP); sigprocmask(SIG_BLOCK, &sa_nact.sa_mask, &sa_nact.sa_mask); sigaction(SIGINT, &sa_nact, &sa_oact); sa_nact.sa_handler = do_stop; sa_nact.sa_flags = 0; sigaction(SIGTSTP, &sa_nact, &sa_oact); puts("sig!"); do { if (count == 2) { sigprocmask(SIG_UNBLOCK, &sa_nact.sa_mask, &sa_nact.sa_mask); printf("un_block ctrl_z
"); } sigpending(&pendmask); if (sigismember(&pendmask, SIGTSTP)) {//SIGINT 。 , SIGQUIT printf("SIGTSTP pending
"); } sleep(2); } while (count < 5); puts("end"); return 0; }

코드 에 두 개의 신호 처리 함수 가 등록 되 어 있 습 니 다. ctrl 입 니 다.z, 그리고 ctrlc 처리, 우선 sigaction 구조의 각 구성원 을 초기 화한 다음 호출
sigemptyset(&sa_nact.sa_mask);
sigaddset(&sa_nact.sa_mask, SIGTSTP);
신호 집합 을 초기 화 한 후 count < = 2 시 에 ctrlz block, count > 2 가 block 을 해제 하면 프로그램 이 실 행 됩 니 다. < 2 시, ctrl 을 여러 번 누 르 면z, unblock 이후 한 번 만 ctrl 을 실행 합 니 다.z 처리
함수, 나머지 신 호 는 버 려 집 니 다.

좋은 웹페이지 즐겨찾기