zoukankan      html  css  js  c++  java
  • Linux学习笔记18——信号1

    一 信号的基本概念

      信号:是向进程发送的软件通知,通知进程有事件发生。

      生成:表示一个信号的产生。

      捕获:表示接收到一个信号。

      信号的寿命:信号的生成和传递之间的时间间隔。

      挂起的信号:已经生成但还未被传递的信号。

    二 产生信号

      每个信号名都是以SIG开头,信号的名字都定义在signal.h中,POSIX必需的信号如下:


      信号         描述 


      SIGABRT       进程放弃(signal abort)

      SIGALRM       告警时钟(signal alarm)

      SIGBUS       访问了内存对象中的为定义部分

      SIGCHLD       子进程被终止,停止或继续(signal child)

      SIGCONT       如果进程被停止了,本信号使进程继续执行(signal continue)

      SIGFPE       算术计算中出现了被零除这样的错误

      SIGHUP       在控制终端(进程)上挂起(死亡)

      SIGILL         无效的硬件指令

      SIGINT        交互终端提示信号(通常是Ctrl-C)

      SIGKILL       终止(signal kill)

      SIGPIPE       向一个没有读程序的管道写入(signal pipe)

      SIGQUIT       交互终端终止(通常是Ctrl-l)(signal quit)

      SIGSEGV        无效的内存引用

      SIGSTOP        执行停止(signal stop)

      SIGTERM       终止(signal terminate)

      SIGTTIN       后台进程试图进行读操作(signal try to input)

      SIGTTOU        后台进程试图进行写操作(signal try to output)

      SIGURG       在套接字上有高速宽数据

      SIGUSR1        用户定义的信号1

      SIGUSR2        用户定义的信号2


      1  函数kill

    #include <signal.h>
    
    int kill(pid_t pid,    //进程ID
         int sig      //信号码
         );          //成功返回0,不成功返回-1并设置errno

      参数pid的取值:>0            kill就向那个ID表示的进程发送信号

               =0      kill就向调用程序的进程组成员发送信号

               -1       kill就向所有它有权发送信息的进程发送信号

              其它负值    就将信号发送到组ID等于|pid|的进程组中去  

      kill的实现必须检测的错误及相应的错误码:EINVAL:sig是一个无效的或不被支持的信号

                          EPERM:调用程序没有适当的权限

                          ESRCH:没有进程或进程组对应于pid

      例子:向进程1000发送SIGUSR1 

    if(kill(1000,SIGUSR1)){
    
        perro("Failed to send the SIGUSR1 signal");
    
    }

      注:查找相关进程ID的常用方法是使用getpid(获取当前进程ID),getppid(获取当前进程的父进程ID),getpgid(获取当前进程的进程组ID),或者通过保存从fork中返回的值来查找。

      2 函数raise

    #include <signal.h>
    
    int raise(int sig);  //成功,返回0,不成功如果sig是无效的,raise函数就将error设置为EINVAL

      raise函数用来向自己发送一个信号。

      例子:使进程向自己发送一个SIGUSR1信号

    if(raise(SIGUSR1)!=0){
    
      perror("Failed to raise SIGUSR1");
    
    }

      3 函数alarm

    #include <unistd.h>
    
    unsigned alarm(unsigned seconds);

      alarm函数用来在seconds秒之后安排发送一个SIGALRM信号,alarm函数从来不报告错误。

    三 对信号掩码和信号集的操作

      信号掩码:当前被阻塞的信号的集合,类型为sigset_t.

      对信号集的操作由以下五个函数组成:

    #include <signal.h>
    
    int sigaddset(sigset_t *set,int signo);        //将signo加入信号集
    
    int sigdelset(sigset_t *set,int signo);        //将signo从信号集中删除
    
    int sigemptyset(sigset_t *set);             //对信号集初始化,使其不包含任何信号
    
    int sigfillset(sigset_t *set);             //对信号集初始化,使其包含所有信号
    
    int sigismember(const sigset_t *set,int signo);   //报告signo是否在*set中,如果在,返回1,否则返回0

      例子:对信号集twosigs进行初始化,使其包含两个信号SIGINT和SIGQUIT

    if((sigemptyset(&twosigs)==-1 || sigaddset(&twosigs,SIGINT)==-1 || sigaddset(&twosigs,SIGQUIT)==-1)){
    
      perror("Failed to set up signal mask");
    
    }

      进程可以用sigprocmask函数来检查或修改它的进程信号掩码,sigprocmask函数可以根据参数how指定的方法修改进程的信号掩码。新的信号掩码由参数set指定,而原先的信号掩码将保存到信号集oset中,声明如下:

    #include <signal.h>
    
    int signalprocmask(int how,                //用来说明信号掩码的修改方式
               const
    sigset_t *restrict set,    //指向一个信号集的指针,在修改中要用到这个信号集,如果为NULL,就说明不需要进行修改
               sigset_t *restrict oset        //如果不为NULL,sigprocmask会将修改之前的信号集放在*oset中返回
               );

      参数how取以下三个值中的一个:

      SIG_BLOCK:向当前被阻塞的信号中添加一个信号集

      SIG_UNBLOCK:从当前被阻塞的信号中删除一个信号集

      SIG_SETMASK:将指定的信号集设置为被阻塞的信号

      例子:将SIGINT添加到进程已经阻塞的信号集中去

    sigset_t newsigset;
    
    if((sigemptyset(&newsigset)==-1 || sigaddset(&newsigset,SIGINT)==-1)){
    
      perror("Failed to initialize the signal set");
    
    }
    
    else if(sigprocmask(SIG_BLOCK,&newsigset,NULL)==-1){
    
      perror("Failed to block SIGINT");
    
    }
  • 相关阅读:
    php2
    11-14php
    三层嵌套
    常见的浏览器兼容
    css中的一些问题及解决方法
    css
    html
    测试题
    正则表达式
    Math对象
  • 原文地址:https://www.cnblogs.com/zjzsky/p/3498582.html
Copyright © 2011-2022 走看看