LINUNX系统编程-----信号

简述

Linux中信号属于软中断,很多比较重要的应用程序都需要处理信号,并利用信号提供了一种异步事件的方法。在实际的应用中,我们可以使用系统提供的信号,也可以让程序响应我们自定义的相关信号。

Linux信号处理的相关函数

函数signal

signal函数是Linux提供的信号机制中最简单的一个接口,函数接口

#include<signal.h>
void signal(int signo,void (*func)(int));
//signo:需要响应的信号值
//func:响应的处理函数

调用该函数时,相当于向内核注册signo信号,然后当进程捕捉到该信号后,调用func进行处理,其中func的参数为int,一般会被指向添加的信号。

信号集

signal可以让进程响应相关的信号,但signal的只能一次对单个信号进行设置。为了方便对进程中多个信号管理,Linux系统提供了一系列接口。

#include<signal.h>
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set,int signo);
int sigdelset(sigset_t *set,int signo);
//若成功:返回0,失败:-1;
int sigismember(const sigset_t *set,int signo);
//若真:返回1,若假:返回0;

对于一个进程,我们可以设定一个sigset_t类型,用来管理进程中的信号,每次需要对信号做相关处理时,则直接在sigset_t上来进行相关处理。另外注意一点在于,信号集管理,只是针对调用进程对信号响应的管理,对回调函数的处理,仍旧交给signal进行信号响应。

下面通过一个例程来了解

#include<iostream>
#include<stdio.h>
#include<errno.h>
#include<unistd.h>
#include<signal.h>
#include<string>
void sigquit(int signo){
  std::cout<<"signo:"<<"sigquit"<<std::endl;
}
int main(){
  /*
   * 这里主要是对信号集的操作
   * 这里对信号集的操作,增删查改
   * */
  sigset_t newmask,oldmask,pendmask;//这里使用一个掩摸去捕获获取设置
  if(signal(SIGQUIT,sigquit)==SIG_ERR)
    perror("SIGQUIT ERRO");
  /*下面则利用信号集来实现*/
  sigemptyset(&newmask);
  sigaddset(&newmask,SIGINT);
  sigaddset(&newmask,SIGQUIT);
  /*这里对SIGBLOCK进行阻塞,然后看后面的pending的设置*/
  if(sigprocmask(SIG_BLOCK,&newmask,&oldmask)<0){
    perror("SIGMASK ERRO");
  }
  sleep(5);
  if(sigpending(&pendmask)<0){
    perror("pending erro:");
  }
  if(sigismember(&pendmask,SIGQUIT))
    std::cout<<"SIGQUIT PENGING"<<std::endl;
  /*然后再进行一个恢复*/
  if(sigprocmask(SIG_SETMASK,&oldmask,NULL)<0)
    perror("SIG_SETMASK ERRO:");
  printf("SIGQUIT unblock");
  sleep(5);
  return 0;
}

执行结果

wlm@wlm:~/code/example/Linux$ ./sig2
^\
SIGQUIT PENGING
signo:sigquit
SIGQUIT unblock

上面的例子中,包含了一些下面将会了解的一些对信号集的相关操作。但可以大致的了解到,信号集的操作与回调函数的设置。

函数sigprocmask

上面对信号集的操作,就是对一个进程下信号集的添加、删除,除了对信号的添加、删除,Linux还提供了一个函数sigprocmask,来对信号集中的信号进行一个“批处理”设置。

#include<signal.h>
int sigprocmask(int how,const sigset_t *restrict set,sigset_t *restrict oset);
//成功:返回0,失败:返回-1 

how提供了三个选择

how说明(针对set)
SIG_BLOCK该进程新的信号屏蔽字和set取并集(原有的和set取并集)
SIG_UNBLOCK取交集(set中存放了希望取消阻塞的信号)
SIG_SETMASK该进程新的信号屏蔽是set指向的值

set为空,则how无意义,oset用来收上一次的屏蔽字。

函数sigpending

#include<signal.h>

int sigpending(sigset_t *set);
//成功返回0,失败返回-1

sigpending的作用,则是返回该进程中被阻塞的信号。

函数sigsuspend

#include<signal.h>
int sigsupend(const sigset_t *sigmask)

当我们设置了一个A信号,并等待响应,但是在实际开发中,可能出现一种情况,在响应A之前,进程突然接收了其他信号,并退出了程序,导致进程还未对A信号进行配置,无法接收,那么sigsuspend的作用,形象点解释,就是sigprocmask后pasue的原子操作,sigsuspend就是要保证信号被配置,并等待(在捕捉到一个信号或发生了一个会终止该进程的信号之前,该进程会被挂起)

函数signaction

对signal升级的安全…待

其他

除了一些基本的信号设置的api外,还有其他一些概念值得我们去注意:可重入函数、信号的可靠去,信号的未决的调解,等问题。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值