Linux信号_总结

对信号本质的理解:

类似于中断,区别在于中断是由硬件产生的,而信号是由软件实现的。

信号的来源:

触发硬件(触发键盘,或是硬件故障);软件信号函数kill 、alarm、setitimer、sigqueue 等函数。

信号的分类:

可靠信号与不可靠信号,实时信号与非实时信号;

不可靠信号:

SIGRTMIN前的信号称为不可靠信号,在早期这段信号可能做出错误的反应,或是丢失。因此对此段信号成为不可靠信号。

可靠信号:

在SIGRTMIN与SIGRTMAX之间的信号称做可靠信号,可靠信号是为了防止信号丢失的。这些信号可以排队处理。

实时信号与非实时信号:

非实时信号都不支持排队,都是不可靠信号;实时信号都是支持排队的,都是可靠信号;

对信号的响应:

响应的三种方式

(1)忽略信号

有两个特殊的信号SIGKILL 和SIGSTOP信号不能被忽略。

(2)捕捉信号

给对应的信号绑定响应的处理函数,带到信号产生时,执行对应的函数。

(3)执行缺省信号

进程对实时信号的缺省反应时进程的终止。

信号的发送:

发送信号的函数有,kill(), alarm(),raise(),setitimer();

(1)kill(int pid, int signal);

PID参数 信号的就收进程
pid>0 进程的ID为pid的进程
pid=0 同一个进程组
pid<0 && pid!=-1 进程组ID为pid绝对值的所有进程
pid=-1 发送至所有ID大于1的进程

参数介绍:

pid为进程号,singnal为信号值。

kill常用于pid>0的信号处理,调用成功返回0,否则返回-1。

(2)alarm(unsigned int seconds)

专门为SIGALRM信号而设函数,seconds表示时间,此函数意味着在seconds秒后向SIGALRM信号发送消息。

进程调用alarm后,以前的alarm()调用都将无效。若调用alarm()前,进程中已经设置了闹钟,则返回上一个闹钟生于的时间,否则返回0;

eg:

#include<signal.h>
#include<stdio.h>
int main(void)
{
printf("first time return:%d\n",alarm(4));
sleep(1);
printf("after sleep(1),remain:%d\n",alarm(2));
printf("renew alarm,remain:%d\n",alarm(1));
}

//运行结果为
first time return:0
after sleep(1),remain:3
renew alarm,remain:2

(3)raise(int signal);

此函数时向本进程发送signal信号的,signal为即将发送的信号值。调用成功返回0;否则返回 -1。

(4)setitimer()函数

int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue));

结构体介绍:

struct itimerval 
{
 struct timeval it_interval;//间隔时间
 struct timeval it_value; //初始时间
 };  

struct timeval
{
   long tv_sec; //秒
   long tv_usec; //微妙
};            

参数描述:

which:表示定时器类型,setitimer有三种定时器类型。

ITIMER_REAL : 以系统真实的时间来计算,它送出SIGALRM信号。  

ITIMER_VIRTUAL : 设定程序执行时间;经过指定的时间后,内核将发送SIGVTALRM信号给本进程;

ITIMER_PROF : 设定进程执行以及内核因本进程而消耗的时间和,经过指定的时间后,内核将发送ITIMER_VIRTUAL信号给本进程;

it_interval指定间隔时间,it_value指定初始定时时间。如果只指定it_value,就是实现一次定时;如果同时指定 it_interval,则超时后,系统会重新初始化it_value为it_interval,实现重复定时;

eg:

#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>

void sigroutine(int signo) {
       switch (signo) {
               case SIGALRM:
                       printf("Catch a signal -- SIGALRM\n");
                       break;
               case SIGVTALRM:
                       printf("Catch a signal -- SIGVTALRM\n");
                       break;
      }
}

int main(int argc, char ** argv) {
       struct itimerval value,ovalue,value2;

       printf("process id is %d\n",getpid());
       signal(SIGALRM, sigroutine); //为SIGALRM信号绑定sigroutine函数
       signal(SIGVTALRM, sigroutine); //为SIGVTALRM信号绑定sigroutine函数

       value.it_value.tv_sec = 1;//设定起始时间
       value.it_value.tv_usec = 0;
       value.it_interval.tv_sec = 1;//设定终止时间
       value.it_interval.tv_usec = 0;
       setitimer(ITIMER_REAL, &value, &ovalue);

       value2.it_value.tv_sec = 0;
       value2.it_value.tv_usec = 500000;
       value2.it_interval.tv_sec = 0;
       value2.it_interval.tv_usec = 500000;
       setitimer(ITIMER_VIRTUAL, &value2, &ovalue);

       for (;;) ;
}

//运行结果为
process id is 3136
Catch a signal -- SIGVTALRM
Catch a signal -- SIGALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGALRM
Catch a signal -- SIGVTALRM
Catch a signal -- SIGVTALRM

安装信号:

由signal()、sigaction()处理:

(1)signal(int signum, sighandler_t handler);

此函数的作用是,为handler函数,或处理过程绑定一个信号,每当出现信号后,进行handler处理。

signum:所指信号;

handler:处理过程,可以时函数的指针。这个也可设置为"SIG_IGN",表示忽略此信号,"SIG_DFL"表示以系统默认方式处理此信号。(注意:SIGKILL SIGSTOP不可被安装)

此函数的例子可参考上一个例子。

(2)sigaction();

int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact));

signum:指定的信号(除SIGKILL,SIGSTOP外)

sigaction:指向结构指针,指定对特定信号的处理

oldact:指向的对象用来保存原来对相应信号的处理

sigaction()函数中第二个参数最为关键。

sigaction结构体如下:

struct sigaction 
{
      void     (*sa_handler)(int);
      void     (*sa_sigaction)(int, siginfo_t *, void *);
      sigset_t   sa_mask;
      int        sa_flags;  //会影响信号接受特殊标志
      void     (*sa_restorer)(void);
  };

(1)结构体中的sa_restorer已经不使用可以忽略。

(2)sa_handler指定的处理函数只有一个参数类似于使用signal()函数

(3)sa_sigaction也是指定信号的处理函数,不过可以带三个参数:

第一个参数为信号值;

第二个参数是指向siginfo_t结构的指针;

第三个参数没有使用;

siginfo_t结构体如下:

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) */
};

(4)sa_mask指定在信号处理程序执行过程中,哪些信号应当被阻塞。缺省情况下当前信号本身被阻塞,防止信号的嵌套发送,除非指定SA_NODEFER或者SA_NOMASK标志位。

注:请注意sa_mask指定的信号阻塞的前提条件,是在由sigaction()安装信号的处理函数执行过程中由sa_mask指定的信号才被阻塞。

(5)sa_flags标志位:

当sa_flags设置为SA_SIGINFO时,示信号附带的参数可以传递到信号处理函数中。即使sa_sigaction指定信号处理函数,如果不设置SA_SIGINFO,信号处理函数同样不能得到信号传递过来的数据,在信号处理函数中对这些信息的访问都将导致段错误。

信号,介绍先到此,如若觉得又不对的地方,请指出,共同进步谢谢!

参考博客有:

https://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index1.html

http://www.cnblogs.com/dandingyy/articles/2653218.html

Linux 对信号的总结的更多相关文章

  1. linux kill信号列表

    linux kill信号列表 $ kill -l1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL5) SIGTRAP      6) ...

  2. Linux进程间通信——信号集函数

    一.什么是信号 用过Windows的我们都知道,当我们无法正常结束一个程序时,可以用任务管理器强制结束这个进程,但这其实是怎么实现的呢?同样的功能在Linux上是通过生成信号和捕获信号来实现的,运行中 ...

  3. linux 自定义信号

    从来没试过linux自定义信号,查了下,说是系统只提供了SIGUSR1和SIGUSR2两个,就两个够吗?更要命的是如果要自定义信号如#define SIG_MYSIG   ....的话要改内核才行,哥 ...

  4. Linux 的信号和线程

    什么是线程 线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元.一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成,每一个程序都至少 ...

  5. Linux之信号

    产生信号五种方法: 按键产生:ctrl+c.ctrl+z.ctrl+\ 系统调用产生:如kill.raise.baort 软件条件产生:如定时器alarm 硬件异常产生:非法访问内存(段错误).除0( ...

  6. Linux&C ——信号以及信号处理

    linux信号的简单介绍 信号的捕捉和处理 信号处理函数的返回 信号的发送 信号的屏蔽 一:linux信号的简单介绍. 信号提供给我们一种异步处理事件的方法,由于进程之间彼此的地址空间是独立的,所以进 ...

  7. Linux&C ——信号以及信号处理

    linux信号的简单介绍 信号的捕捉和处理 信号处理函数的返回 信号的发送 信号的屏蔽 一:linux信号的简单介绍. 信号提供给我们一种异步处理事件的方法,由于进程之间彼此的地址空间是独立的,所以进 ...

  8. linux有关信号的FAQ

    1.为什么会出现系统调用被中断的情况? 进程在执行一个低速系统调用而阻塞期间捕捉到一个信号时,该系统调用就被中断不再继续执行.该系统调用返回出错,其errno被设置为EINTR.这样处理的理由是:因为 ...

  9. Linux 发送信号

    使用kill命令 --在命令行执行kill命令.向指定进程发送信号. 使用kill函数 int kill(pid_t pid,int sig); --参数pid指定一个要杀死的进程,而sig是要发送的 ...

  10. Linux进程间通信-信号

    1.什么是信号信号是Linux系统响应某些条件而产生的一个事件,接收到该信号的进程会执行相应的操作. 2.信号的产生1)由硬件产生,如从键盘输入Ctrl+C可以终止当前进程2)由其他进程发送,如可在s ...

随机推荐

  1. mybatis 日志的使用以及设计

    1.为什么要配置mybtis的logger? mybatis自己设计以及实现了org.apache.ibatis.logging.Log接口. Mybatis为了避免对第三方的日志包存在强依赖,内部的 ...

  2. 使用Linux的环境变量

    许多程序和脚本都使用环境变量来获取系统信息,并存储临时数据和配置信息: 1.什么是环境变量 用来存储关于shell会话和工作环境的信息,就叫做环境变量: bash shell下两种类型: 1.全局变量 ...

  3. OpenCV中Mat的使用

    一.数字图像存储概述 数字图像存储时,我们存储的是图像每个像素点的数值,对应的是一个数字矩阵. 二.Mat的存储 1.OpenCV1基于C接口定义的图像存储格式IplImage*,直接暴露内存,如果忘 ...

  4. OOP AOP

    OOP 一切皆对象,,,对象交互---功能,,,功能叠加---模块,,,模块叠加----系统 AOP   面向切面, 业务逻辑外,添加公共逻辑,增加日志功能,权限控制功能,缓存处理,异常处理,事务,性 ...

  5. iOS如何转换十三位的时间戳

    //将十三位的时间戳转换为日期 - (NSString *)getDate:(NSString *)jsonDate { //jsonDate类似这种/Date(1447659630000)/ NSA ...

  6. 001.[python学习]写在前面的

    0.多动手写写也许你所说的问题就不是问题: 1.最好的帮助文档是dir和help,如下图: 2.如果为了快速完成任务可以选择IDE,否则尽量不要依赖它,因为它的智能导致自己的无能: 3.也许有其他语言 ...

  7. 数据分析与科学计算可视化-----用于科学计算的numpy库与可视化工具matplotlib

    一.numpy库与matplotlib库的基本介绍 1.安装 (1)通过pip安装: >> pip install matplotlib 安装完成 安装matplotlib的方式和nump ...

  8. (22/24) webpack实战技巧:静态资源集中输出

    工作中会有一些已经存在但在项目中没有引用的图片资源或者其他静态资源(比如设计图.开发文档),这些静态资源有可能是文档,也有可能是一些额外的图片,而在打包时保留这些静态资源,直接打包到指定文件夹中.此时 ...

  9. MSMQ 队列消息和死信队列

    日志消息 日志队列可以保存你操作过的消息的备份.它的好处是,一但发现前面的操作失败,可以从日志队列中重新创建出原先的消息对象,然后再进行操作. 例如,向远方发送一个消息对象,然后对方返回一个失败的确认 ...

  10. apache_php_mysql

    软件下载 目前,Apache和PHP均未出现官方的64位版本. Apache 64位: http://www.blackdot.be/?inc=apache/binaries 这个安装文件我已经上传到 ...