Linux signal mechanism (two) - the set of signals

What is the set of signals?

After performing signal processing function receives a signal, if a same signal again, then the signal will be blocked during the execution of the signal processing function, signal processing function performed until the End, then a response signal is blocked, Note that if the signal is received and the signal blocking period, then process multiple signals will be merged into the primary
example being executed SIGUSR1 signal handler, in which case they receive a SIGUSR1 signal, then the signal will be blocked, until after the signal processing function executed, the function is executed again. If during the blocking and received SIGUSER1 signal, then only called once again SIGUSR1 signal handler

Signal is used to set the current record which received the signal, the signal will mark the current location as "processing", if at this time to receive the signal, then the signal is blocked waiting for
the data type sigset_t signal indicating the set, in Linux this type is a 32-bit unsigned integer, which is defined as 32 in Linux types of signals, each signal 32-bit unsigned integer variable to a flag, which if set to 1, then the process is represented by this signal, if set to 0 indicates that the signal can be processed. Note: Some operating systems, the number of signals is more than 32, can not be used at this time indicates a 32-bit integer signal gathered

Function operation signal sets

Function prototypes as follows: [1]

#include <signal.h>

// @brief 清空信号集,全部位置0
int sigemptyset(sigset_t *set);

// 全部位置1
int sigfillset(sigset_t *set);

// 将signo信号对应位置1
int sigaddset(sigset_t *set, int signum);

// 将signo信号对应位置0
int sigdelset(sigset_t *set, int signum);

// 判断该信号集中是否包含指定的信号
int sigismember(const sigset_t *set, int signum);

Again the effect of the set of signals, a signal for a general set filter receiving a signal process
initialization signal if used sigemptyset set () (set of signals all positions 0), then you can receive all the signals
if used sigfillset () set initialization signal (set of signals all positions 1), masking all signals in this case, of course, and SIGKILL signals are not shielded SIGQUIT
meaning sigaddset () and sigdelset () is characterized by a signal or receive a signal to specify the mask

sigprocmask function

This function is used to detect and modify word signal shielding current process (using a signal as a set of mask character signal), the following function prototype: [2]

/*
 * @param how 如何修改当前信号屏蔽字
    * SIG_SETMASK: 直接将第二个参数的信号集进行关联
    * SIG_BLOCK: 当前要设置的信号集与进程目前关联的信号集取并集
    * SIG_UNBLOCK: 取交集
 * @param newSet 要关联的信号集,如果newSet是个空指针(表示只是要获取当前进程的进程屏蔽字),此时how的值无意义
 * @param oldSet 存放当前进程的信号屏蔽字
 * @return 执行成功返回0,否则返回-1
 */
int sigpromask(int how, const sigset_t* newSet, sigset_t *oldSet);

Note: sigprocmask is used only in single-threaded process environment for multi-threaded process using pthread_sigmask ()
Example:

#include <stdio.h>
#include <signal.h>
#include <stdlib.h> // exit
#include <unistd.h> // sleep


void sig_quit(int signo){
    printf("收到了SIGQUIT信号!\n");
}

int main(){
  signal(SIGQUIT, sig_quit);                  // 注册SIGQUIT信号处理函数,SIGQUIT信号可以通过Ctrl+\触发

  sigset_t newSet, oldSet;                    // 定义两个信号集变量
  sigemptyset(&newSet);                       // 清空信号集,全部位置0
  sigaddset(&newSet, SIGQUIT);                // 将SIGQUIT对应的位置1,表示要屏蔽SIGQUIT信号

  sigprocmask(SIG_BLOCK, &newSet, &oldSet);
  printf("进程关联的信号集设置为newSet\n");

  if(sigismember(&newSet, SIGQUIT)){
    printf("SIGQUIT信号被屏蔽了,按ctrl+\\测试\n");
  }

  printf("sleep 10s\n");
  sleep(10);
  printf("sleep end\n");

  sigprocmask(SIG_SETMASK, &oldSet, NULL);
  printf("进程关联的信号集重新设置为oldSet,SIGQUIT信号没有被屏蔽,按ctrl+\\测试\n");
  printf("sleep 10s\n");
  sleep(10);

  return 0;
}

sigaction function

This function is used to view and set up a signal handler. Because of compatibility problems signal function, so the actual development sigaction function instead of using the signal function. Function prototypes as follows: [3]

#include <signal.h>

/*
 * @param signum: 指定要查看和设置的哪个信号的处理函数
 * @param act: 如果非空,表示修改信号的处理函数
 * @param oact: 如果非空,可以通过该参数得到信号之前的处理函数
 * @return 成功返回0,否则返回-1
 */
int sigaction(int signum, const struct sigaction *act,
              struct sigaction *oldact);

struct sigaction {
  void     (*sa_handler)(int);                        // 信号处理函数地址,或者SIG_IGN、SIG_DFL
  void     (*sa_sigaction)(int, siginfo_t *, void *); // 替代的信号处理函数,如果sa_flags为SA_SIGINFO则执行该处理函数
  sigset_t   sa_mask;                                 // 执行信号处理函数时的信号屏蔽字
  int        sa_flags;                                // 选项
  void     (*sa_restorer)(void);                      // The sa_restorer field is not intended for application use
};

The sample code is given in the introduction to collectively function sigsuspend

sigsuspend function

This function can be simply understood as a wait signal blocking occurs, the following function prototype: [4]

#include <signal.h>

/*
 * @param mask:先将mask替换当前进程的信号屏蔽字,之后阻塞进程等待信号发生
 * @return 总是返回-1,可以通过errno值判断是否出错,正常情况errno为EINTR
 */
int sigsuspend(const sigset_t *mask);

Example:

#include <stdio.h>  // printf
#include <string.h> // memset
#include <signal.h> // signal 

void handler_sigusr1(int sig){
  printf("收到了SIGUSR1信号\n");  
}

int main(){
  sigset_t set;
  sigemptyset(&set);

  struct sigaction act;
  memset(&act, 0, sizeof(act));
  act.sa_handler = handler_sigusr1;
  act.sa_mask = set;

  if(sigaction(SIGUSR1, &act, NULL) < 0){
    perror("sigaction error");
  }

  while(1){
    sigsuspend(&set);
  }

  return 0;
}

Introduction The purpose of these functions is to make knowledge bedding package signaling mechanism, how easy to use signaling mechanisms C ++ package, see the blog package signaling mechanism

references

  • [1]. Linux man-pages:man 3 sigemptyset
  • [2]. Linux man-pages:man 2 sigprocmask
  • [3]. Linux man-pages:man 2 sigaction
  • [4]. Linux man-pages:man 2 sigsuspend
Released nine original articles · won praise 0 · Views 234

Guess you like

Origin blog.csdn.net/sdjn_lyn/article/details/104017928