信号的各类函数的作用

大耗子 2020年02月24日 293次浏览

文章链接:https://codemouse.online/archives/87654335678

信号

  • 信号集合变量申请
    sigset_t newmask,oldmask;

  • 将信号集合设置为空
    int sigemptyset(sigset_t *set);

  • 信号集合添加新的信号
    int sigaddset(sigset_t *set, int signum);

  • 从阻塞信号集合变量中删除单一信号
    int sigdelset(sigset_t *set, int signum);

  • 将参数set信号集初始化,然后把所有的信号加入到此信号集里
    int sigfillset(sigset_t *set);

  • 测试信号signum是否包含在信号集合set中
    int sigismember(const sigset_t *set, int signum);

  • 返回在阻塞期间接收到阻塞信号的集合(未决信号)
    sigpending(sigset_t *set)

  • 设置屏蔽的信号集合,并设置信号处理方式
    sigprocmask(SIG_BLOCK,&newmask,&oldmask);
    1.SIG_BLOCK:  该值代表的功能是将newset所指向的信号集中所包含的信号加到
    当前的信号掩码中,作为新的信号屏蔽字(原有信号屏蔽字 + set屏蔽字)。
    2.SIG_UNBLOCK: 将参数newset所指向的信号集中的信号从当前的信号掩码中移除。
    3.SIG_SETMASK: 设置当前信号掩码为参数newset所指向的信号集中所包含的信号

  • 发送信号
    kill(getpid(),SIGUSR2);

  • 自举信号,自己给自己发送信号
    int raise(int sig);

  • 定时发送定时器信号
    单位是秒
    unsigned int alarm(unsigned int seconds);
    例如:
    signal(SIGALRM,print);
    alarm(2); 两秒后发送一次alarm信号

  • 重复定时发送定时器信号,参数是第一次发送和后面重复发送的时间单位是微秒
    useconds_t ualarm(useconds_t usecs, useconds_t interval);

  • 发送信号,携带信息
    union sigval v;
    v.sival_int=100;
    sigqueue(pid,SIGUSR1,v);

  • 将信号绑定函数(收到信号,运行对应函数)返回SIG_ERR,说明绑定失败
    signal(SIGUSR1,handler);

  • 忽略信号
    signal(SIGUSR1,SIG_IGN);

  • 信号函数写法
    void handler(int sig)
    {
    执行代码
    }

  • 多参数信号集合对象
    struct sigaction act, 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); // 一般没啥用
    };
    // act.sa_flags = SA_RESETHAND; 会阻塞信号,使用一次信号后,信号屏蔽失效
    // act.sa_flags = SA_NODEFER; 信号不阻塞
    // act.sa_flags = SA_SIGINFO; 使用sa_sigaction函数的指针
    // act.sa_flags = 0; 会阻塞接受信号

  • 给对象添加指定信号
    sigaction(SIGUSR1, &act, &oact);

  • 信号函数写法
    act.sa_handler = myHandler;
    void myHandler(int sig)
    {
    执行代码
    }

  • 包含更多函数信息的函数申明方式
    act.sa_sigaction=func;
    void func(int signo, siginfo_t *info, void *p)
    {
    printf("signo=%d\n",signo);
    printf("sender pid=%d\n",info->si_pid);
    }

  • 信号结构体

    siginfo_t {
       int      si_signo;    /* Signal number */
       int      si_errno;    /* An errno value */
       int      si_code;     /* Signal code */
       int      si_trapno;   /* Trap number that caused
                                hardware-generated signal
                                (unused on most architectures) */
       pid_t    si_pid;      /* Sending process ID */
       uid_t    si_uid;      /* Real user ID of sending process */
       int      si_status;   /* Exit value or signal */
       clock_t  si_utime;    /* User time consumed */
       clock_t  si_stime;    /* System time consumed */
       sigval_t si_value;    /* Signal value */
       int      si_int;      /* POSIX.1b signal */
       void    *si_ptr;      /* POSIX.1b signal */
       int      si_overrun;  /* Timer overrun count; POSIX.1b timers */
       int      si_timerid;  /* Timer ID; POSIX.1b timers */
       void    *si_addr;     /* Memory location which caused fault */
       long     si_band;     /* Band event (was int in
                                glibc 2.3.2 and earlier) */
       int      si_fd;       /* File descriptor */
       short    si_addr_lsb; /* Least significant bit of address
                                (since Linux 2.6.32) */
    }
    
  • 停下等待,直到收到信号
    pause();

  • 等待除了这个信号集合的其他信号
    sigsuspend(&waitmask)!= -1

  • 设置时间信号的时间间隔,并做备份
    setitimer(ITIMER_VIRTUAL, &value2, &ovalue);

  • 对象的初始化
    struct itimerval value,ovalue,value2;
    value.it_value.tv_sec = 1;
    value.it_value.tv_usec = 0;
    value.it_interval.tv_sec = 1;
    value.it_interval.tv_usec = 0;

  • 获取当前计时器的计时
    getitimer(ITIMER_REAL,&value);
    ITIMER_REAL //数值为0,以系统真实的时间来计算,发送的信号是SIGALRM。
    ITIMER_VIRTUAL //数值为1,以该进程在用户态下花费的时间来计算,发送的信号是SIGVTALRM。
    ITIMER_PROF //数值为2, 以该进程在用户态下和内核态下所费的时间来计算,发送的信号是SIGPROF