$ cat ../apue.h
#ifndef _APUE_H_
#define _APUE_H_

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <assert.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <signal.h>

void err_exit(char *m){
        perror(m);
        exit(EXIT_FAILURE);
}
 

案例一:收到信号后会立即处理

#include "./apue.h"

void handler(int sig){
        printf("sig=%d\n", sig);
}
int main(void){
        struct sigaction act;  //信号结构体
        act.sa_handler=handler; //收到信号后调用的信号处理函数
        sigemptyset(&act.sa_mask);
        act.sa_flags=0;
        if(sigaction(SIGINT, &act, NULL)<0){
                err_exit("sigaction error\n");
        }
        for(;;)
                pause();
        return 0;
}

案例二:收到信号SIGQUIT后,等上一个信号SIGINT处理完毕再处理

#include "./apue.h"

void handler(int sig){
    printf("sig=%d\n", sig);
    sleep(3);
}
int main(void){
    struct sigaction act;
    act.sa_handler=handler;
    sigemptyset(&act.sa_mask);
    sigaddset(&act.sa_mask, SIGQUIT);
    act.sa_flags=0;
    if(sigaction(SIGINT, &act, NULL)<0){
        err_exit("sigaction error\n");
    }
    for(;;)
        pause();
    return 0;
}

 

介绍一些函数:

sigemptyset 函数初始化信号集合set,将set 设置为空.

sigfillset 也初始化信号集合,只是将信号集合设置为所有信号的集合.

sigaddset 将信号signo 加入到信号集合之中,sigdelset 将信号从信号集合中删除.

sigismember 查询信号是否在信号集合之中.s

igprocmask 是最为关键的一个函数.在使用之前要先设置好信号集合set.这个函数的作用是将指定的信号集合set 加入到进程的信号阻塞集合之中去,如果提供了oset 那么当前的进程信号阻塞集合将会保存在oset 里面.参数how 决定函数的操作方式:
SIG_BLOCK:增加一个信号集合到当前进程的阻塞集合之中.
SIG_UNBLOCK:从当前的阻塞集合之中删除一个信号集合.
SIG_SETMASK:将当前的信号集合设置为信号阻塞集合.