linux信号归纳及整理

1.信号的概念

  信号是一种软中断,提供了一种处理异步事件的方法,早期信号是不可靠的,各种系统提供了多少不一样的信号.

   v7  15种

   svr4和4.4bsd 31种

   freebsd,linux,mac os提供了31种

   solaris 提供了38种

   

   linux和solaris支持用户额外定义的信号

   不存在编号为0的信号

   0信号被称作空信号,主要用于kill

2.常见的信号及解释

  1) SIGABRT 夭折信号   调用abort函数产生

  2) SIGALARM 闹钟信号  alarm函数设置的时钟到了产生

 3)SIGSEGV 硬件异常产生信号  除数为0 无效的内存引用
4)SIGURG  网络传来带外数据
5)SIGPIPE 读管道结束,另外进程写管道的时候
6)SIGCHLD 子进程终止 这个是bsd里面的   v系统里面是SIGCLD  含义不一样  需要注意区分
7)SIGTERM 终止信号
8)SIGCONT 让停止的进程继续执行
9)SIGSTOP 暂停一个进程的执行
10)SIGSYS 无效的系统调用
11)SIGTSTP 交互式停止信号
   ctrl+z 终端驱动程序产生此信号,并送至前台组的所有进程
   ctrl+s停止终端的字符输出
   ctrl+q启用终端的输出
12)SIGVTALRM  setitimer函数设置的间隔时间到了
13)SIGUSR1和SIGUSR2用户定义的信号
14)


信号的处理方式
  1)忽略此信号
    除SIGKILL和SIGSTOP信号以外的所有信号都可以被忽略
    硬件异常的信号可以被忽略但是程序的行为未定义
  2)提供捕捉信号的处理函数
    除了SIGKILL和SIGSTOP信号都可以捕获
  3)大多数信号系统的默认动作是终止进程
  4)SIGKILL和SIGSTOP不能阻塞


信号发送函数
 KILL    int  kill(pid_t pid, int signo)
  kill可以用来发送信号 只能发送相同所有者的进程之间, 或者用户是root
  shell命令  kill pid 发送信号SIGTERM给进程pid
             kill -USR1 pid 发送信号SIGUSR1给进程pid
             kill -USR2 pid 发送信号SIGUSR2给进程pid
 Raise   raise(signo) 向进程本身发送信号 kill(getpid(), signo)


 
 关于pid 4种取值的解释
    pid>0 发送给进程pid
    pid == 0 发送信号给当前进程组的所有进程,当然要有权限,且除了系统进程之外
    pid<0  发送给进程|pid|
    pid == -1 发送给有权限的所有进程,除了系统进程之外

kill(pid,0) 如果返回值是-1,errno为esrch 表示该进程肯定不存在了


   

不生成core文件的条件
  1)进程设置了设置用户ID(设置组ID),而当前用户非程序文件的所有者(组所有者)
  2)用户没有写工作目录的权限
  3)文件已经存在,无文件的写权限
  4)文件太大


信号绑定函数
  1) void (*signal(int signo, void(*func)(int)))(int)
     func不一定为函数,  对于func的值signal有三种处理情况
     若func为SIG_IGN,系统会忽略掉这条信号  
     若func为SIG_DFL,系统对进程执行默认的信号处理动作
     若func为函数地址,这个时候如果发生了信号signo,系统才会帮我们去异步调func函数
   signal返回  内部异常会返回error,或者上一次信号处理函数的地址,这个地址就是用于复位的
  信号处理函数如果没有调用exit或longjmp,那么处理函数结束后会继续执行信号发生之前的代码
 
  !!!!signal调一次,就会修改这个程序的默认设置,如果提供函数给别人用,入口处取得值,需要在用完之后复位


不可靠的信号
  信号发生了,进程却没收到,早期的信号是不可靠的,且无阻塞的信号(程序里面必须自定义不退出的循环)


可重入的函数
  信号会造成不可重入函数中断调用,从而造成进程的破坏或数据的错误
  有下面3种情况的函数是不可重入的
  1)使用了静态数据结构 2)调用了malloc或free内存管理函数 3)标准IO函数,因其内部使用了全局数据结构


信号处理函数与errno
  一个线程一个errno
  信号处理函数可能会修改errno值,所以一般的做法是在函数入口保存errno,在返回之前重置errno值


alarm与pause
 alarm(int seconds)
 alarm系统默认的动作是终止进程
  每个进程只能有一个闹钟
  alarm返回上一次设置过的闹钟值的剩余值
  如果seconds是0,取消以前的闹钟
      seconds非0,设置成新的闹钟
 pause挂起一个进程,直到捕捉到一个信号,直到信号处理函数返回,pause才返回.


信号集sigset_t相关操作函数
     sigemptyset 清空信号集
     sigfillset  指定信号集  设置各位为1
     sigaddset   添加信号到信号集
     sigdelset   删除信号集里面的信号
     sigismember 信号集是否含有某个信号


信号屏蔽函数
   单线程
   sigprocmask(int how, sigset_t * set, sigset_t * oset)
   oset非空返回当前的信号集
   set不为空的时候操作
   how  操作
   SIG_BLOCK  现有集和与set求并集
   SIG_UNBLOCK 现有集和与set求交集
   SIG_SETMASK 将set覆盖现有集和

   多线程
   pthread_sigmask

sigaction
   sigaction(int signo, sigaction * act, sigaction * oact)
   如果act不为空就修改相应的数据
   如果oact不为空就返回默认的数据
可以捕获发送信号的来源信息


setjmp和longjmp
  可以跨越函数,而goto不支持
  longjmp调用会导致跳转到setjmp调用定义的位置


sigsetjmp 和 siglongjmp
  signal调用一次就会设置对应位置的信号屏蔽字
  于是sigsetjmp会保存当前进程的信号屏蔽字到jmp_buf,在siglongjmp的时候恢复给当前进程,
  在最后的时候进程的信号屏蔽字又恢复了

 
说白点就是:信号发生的时候,信号处理程序会设置屏蔽字,在结束返回的时候,取消屏蔽字。
如果直接用longjmp和setjmp,那么退出的时候屏蔽字还是存在就响应不了。



sigpending与sigsuspend函数
 sigpending是返回信号集,其中各个信号对于调用进程是阻塞的
 sigsuspend(sigset_t *sigmask)设置信号屏蔽字,然后挂起进程等待捕捉到信号或者终止进程的信号,
 只有从信号处理程序返回的时候,该函数才返回,然后恢复默认信号屏蔽字设置
 sigsuspend的2个作用:保护临界区使其不被信号中断,等待一个信号处理程序设置全局变量

abort 通过raise发送信号SIGABRT 进程异常终止信号


空信号
posxi将编号为0的信号定义为空信号,
kill -0 pid  kill只做正常的错误检查,但不发送信号,如果进程不存在的话,通常会返回ESRCH的错误提示



你可能感兴趣的:(数据结构,linux,kill,Solaris,FreeBSD,Signal)